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

Cómo Crear Eventos Personalizados en tu Servidor de MU Online

Aprende a diseñar, configurar y programar eventos completamente personalizados en tu servidor de MU Online para aumentar la participación de los jugadores.

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

Comprendiendo la Arquitectura de Eventos de MU Online

Antes de escribir una sola línea de configuración, es importante entender cómo el motor del servidor de MU Online gestiona los eventos internamente. La mayoría de los emuladores de servidor de código abierto — incluidos los núcleos Season 6 y Season 9 más utilizados — separan la lógica de eventos en tres capas: el planificador, el manejador de eventos y el despachador de recompensas.

El planificador lee una tabla de tiempos (normalmente un archivo XML o INI) y envía una señal en el momento configurado. El manejador de eventos recibe esa señal, valida las condiciones de los jugadores, pone el mapa de destino en modo evento y gestiona el bucle de juego durante toda la duración. El despachador de recompensas se ejecuta cuando el evento termina, itera sobre los jugadores que cumplen los requisitos y entrega objetos o experiencia a sus inventarios.

Comprender esta separación es fundamental porque los errores de configuración en cada capa producen síntomas diferentes. Un error en el planificador significa que el evento nunca arranca. Un error en el manejador significa que el evento arranca pero se comporta de forma incorrecta. Un error en el despachador significa que el evento termina pero los jugadores no reciben nada.

Nota: Los nombres de archivo y las claves de parámetros descritos en esta guía siguen las convenciones de los codebases IGCN y OpenMU. Si usas un núcleo diferente, la estructura es casi siempre la misma — solo difieren los nombres de archivo y algunos nombres de parámetros. Consulta siempre tu propio código fuente antes de aplicar cambios.

Definiendo el Evento en el Archivo de Configuración

Los eventos personalizados se definen en el archivo EventSchedule.xml (o EventConfig.ini en núcleos más antiguos) ubicado en el directorio GameServer/Data/. Cada evento ocupa su propio bloque y requiere como mínimo cinco parámetros: un identificador único, un mapa de destino, una hora de inicio, una duración y un número mínimo de jugadores.

A continuación se muestra un ejemplo completamente anotado de un evento personalizado de Invasión de Jefe Antiguo:

[CustomEvent]
EventID         → 1001
EventName       → "Invasión del Jefe Antiguo"
TargetMap       → 32          ; Índice del mapa para Kanturu Relics
StartTime       → 20:00       ; Hora del servidor en formato 24 horas
Duration        → 30          ; Duración en minutos
MinPlayers      → 5           ; El evento se cancela si hay menos jugadores
MaxPlayers      → 50          ; Límite máximo aplicado al entrar al mapa
AllowedClasses  → 0,1,2,3,4  ; Todas las clases estándar permitidas
EntryLevel      → 300         ; Nivel mínimo del personaje para entrar
EntryFee        → 0           ; Coste en Zen para entrar (0 = gratis)
RecurRule       → DAILY       ; DAILY | WEEKLY | ONCE | INTERVAL
RecurInterval   → 0           ; Solo se usa cuando RecurRule = INTERVAL (minutos)

[BossSpawn]
BossID          → 447         ; ID del monstruo en MonsterList.xml
SpawnX          → 128
SpawnY          → 128
SpawnCount      → 1
RespawnOnDeath  → false

[RewardItem]
WinnerCount     → 3           ; Los 3 jugadores con más daño reciben la recompensa
ItemID          → 13          ; Alas
ItemIndex       → 38          ; Tipo de ala específico
ItemLevel       → 15
ItemSkill       → true
ItemLuck        → false
ItemOpt         → 7

[Announcement]
PreEventMsg     → "¡La Invasión del Jefe Antiguo comienza en 5 minutos! Ve a Kanturu Relics."
StartMsg        → "¡El Jefe Antiguo ha aparecido en Kanturu Relics! Derrótalo para obtener recompensas legendarias."
EndMsg          → "¡El Jefe Antiguo ha sido derrotado! Las recompensas han sido distribuidas."
Channel         → GLOBAL      ; GLOBAL | GUILD | NOTICE

Guarda el archivo y no reinicies el servidor todavía. Aún debes registrar el evento con el planificador y verificar la cadena de recompensas.

> [!ATENCION] > Nunca uses valores de EventID por debajo de 1000 para eventos personalizados. El juego base reserva los IDs del 1 al 999 para eventos integrados como Blood Castle, Devil Square y Chaos Castle. Reutilizar un ID reservado hará que tu evento personalizado sobreescriba el comportamiento del evento original, lo cual es extremadamente difícil de depurar.

Registrando el Evento con el Planificador

El archivo del planificador (EventScheduler.xml o Schedule.ini) mantiene una lista maestra de todos los eventos que el motor debe rastrear. Añadir tu evento aquí es lo que hace que el servidor realmente lo cargue y ejecute. Sin este paso, el bloque de configuración que escribiste en la sección anterior se analiza sintácticamente pero nunca se activa.

Localiza la sección <EventList> y añade tu entrada:

<EventList>
  <!-- Eventos integrados por encima de esta línea — no modificar -->

  <Event id="1001" enabled="true" priority="normal" log="true" />
</EventList>

El parámetro priority acepta los valores low, normal y high. Los eventos de alta prioridad tienen preferencia sobre las transiciones de mapa que de otro modo los interrumpirían. Usa high solo para eventos que nunca deban ser cancelados por los ciclos de mantenimiento rutinario del servidor.

El indicador log="true" escribe una entrada con marca de tiempo en Logs/EventLog.txt cada vez que el evento empieza, termina o se cancela. Activa siempre el registro durante el desarrollo y las pruebas. Puedes desactivarlo más adelante cuando el evento lleve varias semanas funcionando de forma estable.

Después de guardar ambos archivos, realiza un reinicio controlado del servidor durante una ventana de baja población. Observa la salida de la consola durante el arranque en busca de líneas que comiencen con [EventScheduler]. Una carga exitosa tiene este aspecto:

[EventScheduler] Loaded event ID 1001 → "Invasión del Jefe Antiguo" → next run: 20:00

Si aparece [EventScheduler] WARNING: Event ID 1001 skipped — invalid map index, el valor de TargetMap no coincide con ningún mapa registrado en tu MapData.xml. Corrige el índice y reinicia de nuevo.

Pruebas e Iteración sobre la Lógica del Evento Personalizado

Probar un evento basado en tiempo durante el desarrollo es poco práctico si hay que esperar hasta la hora programada. Todos los núcleos de servidor principales exponen un comando de consola de GM que fuerza el inicio inmediato de un evento independientemente del horario.

Conéctate con una cuenta de nivel GM y ejecuta:

/eventstart 1001

Si el comando no se reconoce, tu núcleo usa un prefijo diferente. Revisa el archivo GMCommandList.xml o equivalente. Las alternativas más comunes son /eventforce, /startevent y /gm_event.

Una vez que el evento se dispare, verifica estos comportamientos en secuencia:

  • El mensaje de anuncio aparece en el chat global
  • Los jugadores con el nivel correcto y en el mapa correcto reciben el portal de entrada
  • El jefe aparece en las coordenadas configuradas
  • El temporizador del evento cuenta hacia atrás correctamente en la interfaz
  • Cuando el jefe muere (o el tiempo expira), el despachador de recompensas se ejecuta y los objetos se entregan

> [!CONSEJO] > Crea un personaje de prueba dedicado en el nivel mínimo permitido con una segunda cuenta GM conectada simultáneamente. Esto te permite validar la restricción de nivel de entrada y la entrega de recompensas en una sola sesión de prueba sin necesidad de involucrar a jugadores reales. Usa el comando /additem para dar a tu personaje de prueba espacio de inventario provisional si es necesario.

Personalización Avanzada: Lógica Condicional y Eventos Encadenados

Una vez que tu evento base es estable, puedes introducir lógica condicional para hacerlo más dinámico. El manejador de eventos admite una capa de scripting sencilla en la mayoría de los núcleos Season 6 o superiores, a la que se accede mediante un bloque de script en línea dentro de la configuración.

Un patrón habitual es el evento encadenado, donde completar el primer evento desbloquea un segundo:

[ChainEvent]
TriggerEventID    → 1001        ; Este evento se dispara cuando 1001 termina con éxito
ChainEventID      → 1002        ; EventID del evento de seguimiento
TriggerCondition  → BOSS_KILLED ; BOSS_KILLED | TIME_EXPIRED | PLAYER_COUNT
DelayAfterTrigger → 2           ; Minutos de espera antes de iniciar el evento encadenado

Los eventos encadenados son muy potentes para construir contenido de múltiples fases — por ejemplo, matar a un jefe que inmediatamente abre una sala del tesoro con una ventana de saqueo de 2 minutos. Limita las cadenas a un máximo de tres etapas. Las cadenas más largas introducen una complejidad de gestión de sesión que puede provocar corrupción del estado del evento si un jugador se desconecta a mitad de la cadena.

Documenta siempre cada evento personalizado en un registro de administración local, anotando el EventID, el propósito, la fecha de creación y cualquier problema conocido. Esta práctica resulta invaluable cuando se transfieren responsabilidades de administración del servidor o se diagnostican conflictos meses después de la implementación inicial.

Perguntas frequentes

¿Puedo ejecutar varios eventos personalizados al mismo tiempo?

Sí, siempre que cada evento utilice un EventID distinto y el servidor tenga memoria suficiente asignada. Los eventos que comparten el mismo mapa pueden generar conflictos, por lo que conviene usar instancias de mapa únicas o escalonar los horarios de inicio con al menos 5 minutos de diferencia.

¿Qué ocurre si el servidor se cae durante un evento?

Los eventos personalizados no se reanudan automáticamente tras una caída a menos que implementes un script de recuperación que lea el registro de eventos y reinicialice el estado. Se recomienda encarecidamente hacer una copia de seguridad del estado del evento en un archivo plano o en una tabla de base de datos cada 60 segundos durante los eventos activos.

¿Cómo restrinjo un evento a una clase de personaje específica?

Usa el parámetro AllowedClasses en el bloque del evento. Indica los IDs de clase separados por comas, por ejemplo AllowedClasses = 0,1,2. Consulta el archivo de enumeración de clases de tu código fuente para obtener los valores numéricos correctos.

¿Es posible entregar objetos que no estén en la tabla de drop estándar?

Sí. Define el objeto de recompensa usando su ItemID e ItemLevel directamente en el bloque RewardItem de la configuración del evento. El objeto no necesita aparecer en ninguna tabla de drop, pero debe existir en los archivos de definición del ItemManager.

EQ

Equipo ViciadosMU

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

Sigue leyendo

Artículos relacionados