Invasions

Scheduled monster invasions across the world. Each invasion is its own self-contained XML file under Data/Event/Invasions/. Up to 30 invasions are supported.

The legacy InvasionManager.dat file is no longer read. Every invasion now has its own schedule, message strings, spawn map groups, and monster table inside one XML.

File Location#

Data/Event/Invasions/<NNN> - <Name>.xml

The 3-digit NNN prefix is the stable numeric index used by ForceStart, the /invasion console command, and EventTimerSlot binding. Anything after - is decorative and ignored by the loader. Inside the XML, <General Name="..."/> is the human-readable label.

Loaded once at GameServer startup. Gated by Event.dat InvasionManagerSwitch. Use the in-server GUI Reload action (or restart) to re-scan the folder after edits.

Default invasions shipped#

FileEventTimerSlot
000 - Skeleton King.xml14
001 - Red Dragon.xml15
002 - Goldens.xml16
003 - White Wizard.xml17
004 - New Year.xml-1 (no client timer)
005 - Rabbits.xml-1
006 - Summer.xml-1
007 - Cursed Santa.xml21
008 - Medusa.xml22

Add a new invasion by dropping in <NNN> - <whatever>.xml with a free NNN (0-29).

XML Layout#

<?xml version="1.0" encoding="utf-8"?>
<Invasion>
  <General .../>
  <Messages>...</Messages>
  <Schedule>...</Schedule>
  <MapGroups>...</MapGroups>
  <Monsters>...</Monsters>
</Invasion>

<General> attributes#

AttributeTypeDefaultEffect
Namestring"Unnamed"Human-readable invasion name (logs, GUI, message substitutions)
DurationSecint600Maximum run time in seconds. Invasion ends on timeout, boss-policy satisfied, or all monsters dead
MinOnlineUsersint0Pre-start gate. If fewer players are online, the invasion is postponed (and NotEnoughPlayers message is broadcast if configured)
AnnounceLeadSecint60Seconds before start to broadcast AnnounceBeforeStart
AnnounceMessageTypeenumDisabledDisabled or GoldenCenter. Render style for the pre-start announce
FinalMessageTypeenumDisabledSame enum; render style for Start / End
MonsterCountMessageTypeenumDisabledSame enum; render style for MonsterKilled progress messages
EventTimerSlotint-1Slot ID broadcast over C2:F3:E9 for the client event-timer UI. -1 = no client broadcast
BossEndPolicyenumFirstFirst = any boss kill ends the invasion. All = invasion runs until every spawned boss dies. Never = boss kills never end the invasion; ends only on timer or when all monsters (trash + bosses) are dead
ClusterAroundBoss0 or 101 = trash monsters spawn within ClusterRadius tiles of the boss anchor. 0 = trash scatters independently across the MapGroup rectangle
ClusterRadiustiles20Radius used when ClusterAroundBoss=1

<Messages>#

Optional chat / center-screen strings. Empty children are silent.

ElementWhen broadcastSubstitutions
<AnnounceBeforeStart>AnnounceLeadSec before start{0} = seconds remaining
<Start>Invasion beginsnone
<End>Invasion ends (timer / boss / cleanup)none
<NotEnoughPlayers>Start gated by MinOnlineUsers{0} = additional players needed
<MonsterKilled>Trash monster death (rendered via MonsterCountMessageType){0} killer name, {1} monster class name (from Monster.xml)
<BossKilled>Boss death{0} killer name, {1} map, {2} X, {3} Y, {4} boss class name (from Monster.xml)

<Schedule>#

Each <Entry> is one calendar firing time. Multiple entries = multiple firings per day. Wildcard * matches any value.

<Entry Year="*" Month="*" Day="*" DoW="*" Hour="0"  Min="50" Sec="0" />
<Entry Year="*" Month="*" Day="*" DoW="*" Hour="12" Min="50" Sec="0" />

Attributes: Year, Month, Day, DoW (day of week, 0-6), Hour, Min, Sec. All accept * for "any".

<MapGroups>#

Spawn-anchor rectangles. The runtime picks one <Group> row per matching Index/SubIndex pair when the invasion fires and uses that rectangle to position monsters.

<Group Index="0" SubIndex="0" Map="0" X1="10" Y1="10" X2="240" Y2="240"/>
<Group Index="0" SubIndex="1" Map="2" X1="10" Y1="10" X2="240" Y2="240"/>
<Group Index="0" SubIndex="2" Map="3" X1="10" Y1="10" X2="240" Y2="240"/>
AttributeEffect
IndexGroup ID. Must match a value in <Monsters>
SubIndexAlternate spawn region for the same group. One is selected at random per invasion cycle
MapTarget map index (MapManager.xml)
X1, Y1, X2, Y2Spawn rectangle bounds (tile coords)
CommentOptional, ignored by loader

<Monsters>#

Per-group spawn definitions. Every matching <Monster> row spawns Count instances of MonsterClass.

<Monster GroupIndex="0" SubIndex="0" MonsterClass="135" Range="30" Count="1"
         Boss="1" RegenType="0" RegenTimeSec="0" ItemBag="27" MinUsersToSpawn="-1"/>
AttributeEffect
GroupIndexMatches MapGroups/<Group Index>
SubIndexMatches MapGroups/<Group SubIndex>. Only rows whose SubIndex matches the chosen MapGroup spawn this cycle
MonsterClassMonster class index (Monster.xml)
RangeRandom scatter radius around the anchor point (tiles)
CountHow many instances to spawn
Boss1 = counted by BossEndPolicy and triggers BossKilled on death. 0 = trash mob
RegenType0 = no respawn during invasion. Non-zero = respawn after RegenTimeSec, on a free tile within 5 of where it last spawned. An invasion with respawning monsters never ends by "all killed": it ends on its timer (or the boss end rule)
RegenTimeSecRespawn delay in seconds when RegenType != 0
ItemBagEventItemBag entry granted on death. -1 = no bag drop (EventItemBag.xml)
MinUsersToSpawnPopulation gate per-monster. -1 = always spawn. Otherwise spawn only when online users >= this value
CommentOptional, ignored

Runtime hooks#

  • GUI: GameServer's invasion panel exposes Start / Reload / state inspection per invasion.
  • GS console: /invasion start <NNN> and /invasion start <name> force-fire bypass schedule + online gate.
  • EventTimerInfo: invasions with EventTimerSlot >= 0 broadcast remaining time / state to the client tooltip system. See EventTimerInfo.xml.
  • HUD: active invasion state is mirrored to a dedicated client HUD. The HUD lists up to 16 concurrent event rows per page; with more than 16 active at once the extra rows are not shown.

Cross-File Dependencies#

ValueRelated in
Master enableEvent.dat InvasionManagerSwitch
MonsterClassMonster.xml
MapMapManager.xml
ItemBagEventItemBag.xml
EventTimerSlot name + tooltipEventTimerInfo.xml

Common Issues#

  • Invasion never triggers - InvasionManagerSwitch = 0 in Event.dat; or all <Schedule> entries have past times for the day; or MinOnlineUsers not met
  • Monsters do not spawn - <Monster> SubIndex does not match the <Group SubIndex> randomly chosen this cycle; or MapGroups rectangle lands on non-walkable tiles
  • Boss spawns but no announcement - <BossKilled> element empty, or EventTimerSlot not configured for HUD readback
  • Invasion ends too early on a boss kill - BossEndPolicy="First" ends on any boss death. "All" ends on the last boss death - with only one boss spawned it behaves identically to "First" (the only kill is the last kill). Use "Never" to let the event run until the timer or all monsters (trash + bosses) are dead, regardless of boss kills
  • Monsters keep respawning mid-invasion - RegenType != 0; set to 0 for single-wave behavior
  • Two invasions at the same time - intended when distinct files have overlapping schedule entries. Use different <Schedule> times to sequence
  • Edits ignored after Reload - file lacks <Invasion> root, or NNN prefix collides with another file (loader keeps first, logs the rest)

Last updated October 6, 2026