MonsterAIRule.xml

Defines conditional rules that temporarily override a monster class's active AI Unit based on calendar date and time. While a rule is active, every live monster of the target class switches from its BasicAI to the rule's Unit until the rule expires.

File Location#

Data/Monster/MonsterAIRule.xml

Dependencies#

Depends OnPurpose
MonsterAIUnit.xmlSupplies the replacement AI personality
MonsterAIGroup.xmlAssigns each monster's BasicAI (the rule's fallback)
Monster.xmlDefines the monster classes referenced by Class
Used ByPurpose
Monster AI dispatcherEvaluates every rule on each AI tick and applies overrides

How It Works#

  1. The AI dispatcher walks the rule list on every AI tick.
  2. Each rule is tested against the current server clock (and, when relevant, server events).
  3. If a rule is valid and past its WaitTime but still inside WaitTime + ContinuanceTime, the target class is tagged with the rule's Unit.
  4. On the next AI update, every live monster of that class has its CurrentAI switched to that Unit; its BasicAI is preserved untouched.
  5. When no rule is active for the class, monsters fall back to BasicAI from MonsterAIGroup.xml.

Current Status#

<?xml version="1.0" ?>
<MonsterAIRule/>

Configuration Structure#

Rule Attributes#

AttributeTypeRequiredDescription
NumberintYesRule identifier (informational)
ClassintYesTarget monster class (from Monster.xml). All live monsters of this class are affected
DescriptionstringNoHuman-readable label, up to 99 characters
UnitintYesAI Unit that replaces BasicAI while the rule is active. Must exist in MonsterAIUnit.xml
ConditionintYesCondition type. See below. Only 1 is functional
WaitTimeintYesSeconds to wait after the condition first becomes true before the override starts
ContinuanceTimeintYesSeconds the override remains active after WaitTime elapses
Monthint/stringConditionalMonth 1-12, or * for any
Dayint/stringConditionalDay of month 1-31, or * for any
WeekDayint/stringConditionalDay of week 1-7 where 1 = Sunday and 7 = Saturday, or * for any
Hourint/stringConditionalHour 0-23, or * for any
Minuteint/stringConditionalMinute 0-59, or * for any

Condition Types#

ConditionDescriptionDate/Time Fields Used
1Specific calendar date/timeMonth, Day, WeekDay, Hour, Minute
71Crywolf event startHard-coded to always return false
72Crywolf event endHard-coded to always return false

Important Behavior#

Timing Logic#

condition first TRUE -> wait [WaitTime]s -> override ACTIVE for [ContinuanceTime]s -> override EXPIRES

Example with WaitTime="10" and ContinuanceTime="3600":

  • 00:00:00 - condition becomes true
  • 00:00:10 - override activates (10 s wait elapsed)
  • 01:00:10 - override expires (3600 s duration elapsed)

Both WaitTime and ContinuanceTime are in seconds. ContinuanceTime="60" means one minute, not one hour.

Date/Time Matching#

  • All non-wildcard fields must match simultaneously for the condition to be true.
  • WeekDay is tested first. A mismatch short-circuits the rule as invalid for the current tick.
  • Month, Day, Hour, Minute each build a "valid from" timestamp when their field differs from the current clock. The rule stays valid from that timestamp through WaitTime + ContinuanceTime past it.
  • Matching is minute-precision. Firing resolution is the AI dispatcher tick (sub-second).

Multiple Rules Per Class#

Rules are evaluated in file order and all write to the same per-class override slot:

  • The last rule in the file that touches a given Class determines the outcome for that class.
  • If the last-listed rule for a class is valid, its Unit is applied.
  • If the last-listed rule for a class is invalid (its condition is false or outside the timing window), the override slot is cleared even if an earlier rule for the same class was valid.

Order rules for the same class so the one you actually want to win is listed last, or keep one rule per class to avoid the overwrite.

Fallback to BasicAI#

When no active rule targets a monster's class, that monster uses its BasicAI assigned by MonsterAIGroup.xml. The override never modifies BasicAI itself; it only swaps the runtime CurrentAI pointer.

Performance#

Every rule is checked against the clock on every AI tick, and every live monster of an overridden class has its CurrentAI pointer rewritten on every AI tick. Keep the rule list small. The loader caps it at 200 entries.

Examples#

Golden Goblins (class 8) switch to an aggressive Unit for all of October 31:

<MonsterAIRule>
  <Rule
    Number="1"
    Class="8"
    Description="Halloween aggressive Golden Goblin"
    Unit="101"
    Condition="1"
    WaitTime="0"
    ContinuanceTime="86400"
    Month="10"
    Day="31"
    WeekDay="*"
    Hour="*"
    Minute="*"
  />
</MonsterAIRule>
  • Activates at October 31 00:00 server time.
  • Runs for 86400 s (24 h).
  • Every Golden Goblin on the server swaps to Unit 101.

Common Issues#

Use Cases#

Time-Based Events#

  • Night aggression: lower DelayTime Unit during dark hours
  • Weekend bosses: swap to boss-behaviour Units on Saturday/Sunday
  • Hourly rotations: multiple classes each with their own schedule

Seasonal Events#

  • Halloween behaviour on October 31
  • December festive patterns
  • Anniversary overrides

Dynamic Difficulty#

  • Peak-hour challenge: harder Units during prime-time
  • Off-peak: easier Units overnight

When NOT to Use MonsterAIRule#

NeedBetter Solution
Permanent behaviour changeEdit MonsterAIGroup.xml StartAI directly
HP-based skill triggersUse MonsterSkill.xml
Timed spawn/despawnUse event spawn types in MonsterSetBase/ per-map XML
Event-only monstersAdd dedicated monster classes
Stat tweaksEdit Monster.xml

Last updated May 17, 2026