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#
| File | EventTimerSlot |
|---|---|
000 - Skeleton King.xml | 14 |
001 - Red Dragon.xml | 15 |
002 - Goldens.xml | 16 |
003 - White Wizard.xml | 17 |
004 - New Year.xml | -1 (no client timer) |
005 - Rabbits.xml | -1 |
006 - Summer.xml | -1 |
007 - Cursed Santa.xml | 21 |
008 - Medusa.xml | 22 |
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#
| Attribute | Type | Default | Effect |
|---|---|---|---|
Name | string | "Unnamed" | Human-readable invasion name (logs, GUI, message substitutions) |
DurationSec | int | 600 | Maximum run time in seconds. Invasion ends on timeout, boss-policy satisfied, or all monsters dead |
MinOnlineUsers | int | 0 | Pre-start gate. If fewer players are online, the invasion is postponed (and NotEnoughPlayers message is broadcast if configured) |
AnnounceLeadSec | int | 60 | Seconds before start to broadcast AnnounceBeforeStart |
AnnounceMessageType | enum | Disabled | Disabled or GoldenCenter. Render style for the pre-start announce |
FinalMessageType | enum | Disabled | Same enum; render style for Start / End |
MonsterCountMessageType | enum | Disabled | Same enum; render style for MonsterKilled progress messages |
EventTimerSlot | int | -1 | Slot ID broadcast over C2:F3:E9 for the client event-timer UI. -1 = no client broadcast |
BossEndPolicy | enum | First | First = 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 |
ClusterAroundBoss | 0 or 1 | 0 | 1 = trash monsters spawn within ClusterRadius tiles of the boss anchor. 0 = trash scatters independently across the MapGroup rectangle |
ClusterRadius | tiles | 20 | Radius used when ClusterAroundBoss=1 |
<Messages>#
Optional chat / center-screen strings. Empty children are silent.
| Element | When broadcast | Substitutions |
|---|---|---|
<AnnounceBeforeStart> | AnnounceLeadSec before start | {0} = seconds remaining |
<Start> | Invasion begins | none |
<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"/>
| Attribute | Effect |
|---|---|
Index | Group ID. Must match a value in <Monsters> |
SubIndex | Alternate spawn region for the same group. One is selected at random per invasion cycle |
Map | Target map index (MapManager.xml) |
X1, Y1, X2, Y2 | Spawn rectangle bounds (tile coords) |
Comment | Optional, 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"/>
| Attribute | Effect |
|---|---|
GroupIndex | Matches MapGroups/<Group Index> |
SubIndex | Matches MapGroups/<Group SubIndex>. Only rows whose SubIndex matches the chosen MapGroup spawn this cycle |
MonsterClass | Monster class index (Monster.xml) |
Range | Random scatter radius around the anchor point (tiles) |
Count | How many instances to spawn |
Boss | 1 = counted by BossEndPolicy and triggers BossKilled on death. 0 = trash mob |
RegenType | 0 = 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) |
RegenTimeSec | Respawn delay in seconds when RegenType != 0 |
ItemBag | EventItemBag entry granted on death. -1 = no bag drop (EventItemBag.xml) |
MinUsersToSpawn | Population gate per-monster. -1 = always spawn. Otherwise spawn only when online users >= this value |
Comment | Optional, 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 >= 0broadcast 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#
| Value | Related in |
|---|---|
| Master enable | Event.dat InvasionManagerSwitch |
MonsterClass | Monster.xml |
Map | MapManager.xml |
ItemBag | EventItemBag.xml |
EventTimerSlot name + tooltip | EventTimerInfo.xml |
Common Issues#
- Invasion never triggers -
InvasionManagerSwitch = 0in Event.dat; or all<Schedule>entries have past times for the day; orMinOnlineUsersnot met - Monsters do not spawn -
<Monster>SubIndexdoes not match the<Group SubIndex>randomly chosen this cycle; orMapGroupsrectangle lands on non-walkable tiles - Boss spawns but no announcement -
<BossKilled>element empty, orEventTimerSlotnot 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 to0for 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, orNNNprefix collides with another file (loader keeps first, logs the rest)