Skip to main content

Creature AI and Skillsets

This document describes how Ragnarok Online's zone servers determine the behavior of AI-enabled actors in the game world.

Model of AI Behavior

The behaviors of ingame actors can be sorted into a few basic categories:

  • Movement: Random walks, following parents, and chasing targets
  • Combat: Reacting to attacks/spellcasts, target selection (including AOI checks)
  • Looting: Picking up items from the floor, and moving to an item's location

This kind of logic is represented by a set of state transitions, here called AI preset, and assigned to creatures. It can also be changed on the fly to enable more complex reactions and facilitate somewhat dynamic reactions to gameplay situations.

Then, there's two additional categories worth exploring separately:

  • Skills: Abilities that are defined for each creature type, and specific to only it
  • NPC Events: Unrelated to creatures, they're behind regular dialogs and player-NPC interactions

The first is implemented via a set of predefined rules making up the skill usage patterns for a given unit class (monster type), which is called the monster's skillset. Skills are then used based on the current state and probabilities for each configured event.

NPC events are a special case and only apply to regular (non-creature) NPCs, which are technically using the same framework but with fewer, specialized states and no transitions. The state of NPC actors doesn't really change, so they're always "Idle".

AI State Changes

A finite state machine (FSM) represents the behavior of each actor. The state of this machine changes based on inputs provided by ingame events, which the zone server feeds into the FSM as part of its World State Update loop. After processing an input, the server emits another event as the FSM's output, to be processed in the same update loop - or possibly in the next iteration.

List of AI States

The list of supported AI states is short, but their interpretation isn't always straight-forward:

State IDInterpretationDescription
ABNORMAL_STStatusImpacted by loss of control effects that prevent it from acting normally
ANGRY_STEnragedAggressively attacking or chasing target, using an alternate behavior set (switches after being attacked)
BERSERK_STAttackingIn range and actively attacking their target
DEAD_STDeadCurrently removed from the map (inactive until respawn)
FOLLOW_SEARCH_STScanning (Follow)Seeking new targets in the area of interest, while following a parent unit
FOLLOW_STFollowingMoving to a new location, while following a parent unit
IDLE_STIdleNo action is currently in progress (default)
MOVEITEM_STLootingMoving towards an item, with the intent to loot it
RMOVE_STWalkingMoving (random walk, when not in combat)
RUSH_STPursuingChasing down a target (player), with the intent to attack it
SEARCH_STScanningMonitoring the area of interest to find new targets

Source: Kokotewa's RO database (contains the AI states, presets, and transitions for any given creature)

Some more details about the (somewhat confusing) ANGRY_ST state:

Angry: These mobs are "hyper-active". Apart from "chase"/"attack", they have the states "follow"/"angry". Once hit, they stop using these states and use the normal ones. The new states are used to determine a different skill-set for their "before attacked" and "after attacked" states. Also, when "following", they automatically switch to whoever character is closest.

Source: Hercules documentation (also contains other information about the AI system)

Input and Output Events

caution

This section contains unverified information and/or speculation. It may or may not be completely wrong.

AI state changes are triggered by certain game events, which serve as input to the underlying FSM. Similarly, state transitions emit output events which can then influence the game world. The exact order this happens isn't entirely clear, but there's some evidence the output events are emitted some time before the resulting state transition is executed:

The term spawn is misleading as monsters don’t technically die, rather monsters are temporarily removed from the map. This is important because when a monster is returned to the map the monster AI will remain in the previous state, e.g. if a monster is aggressive to a player, and were to respawn near that player, it will remain aggressive towards that player. While this is rarely encountered due to a combination of horizontal/vertical position variance and non-zero regeneration timers it does explain otherwise inexplicable behavior, e.g. an ordinarily passive monster respawning with aggressive behavior.

Source: Kokotewa's blog

For any of that to happen, it would be necessary for state changes to have the ability to override each other... like so:

  1. Creature is "killed" (removed from map) and flagged as "dead" (regenerating)
  2. The respawn timer expires, which triggers the regeneration logic
  3. The creature is revived in its original AI state (output event triggers here)
  4. It "spawns" next to a player, still in its original AI state
  5. The player's proximity triggers the appropriate input event
  6. The creature immediately attacks the player, switching AI states
  7. The "idle" output state is never reached, because another transition overrode it

If there was no player to attack when the creature respawns, it should follow that instead of 5 to 7, the output state will then be set (after the "scanning for targets" step). Since anecdotal evidence for such situations is plentiful, that's probably what's going on in the background. This is of course mere conjecture, but there's no other explanation for the aforementioned phenomenon.

List of Input Events

These are the ingame events that can trigger FSM state transitions:

IDDescriptionScope
ARENASTART_INSome "arena" (PVP) event was started (?)NPC
ARRIVEDAT_ITEM_INThe creature arrived at the location of the item it is currently trying to lootMOB
ATTACKED_INThe creature was attacked (by a player?)MOB
CHANGE_NORMALST_INAll loss of control effects were removed from the creatureMOB
CHARACTER_ATTACKSIGHT_INA player entered the creature's attack range (on their own?)MOB
CHARACTER_INATTACKSIGHT_INThe creature reached the targeted unit and is now within attack rangeMOB
CHARACTER_INSIGHT_INA player entered the creature's area of interestMOB
CLICK_INThe NPC was clicked (player started interacting with it)NPC
DEADSTATE_TIMEOUT_INThe respawn timer for the creature has elapsedMOB
DESTINATION_ARRIVED_INThe creature has arrived at the target location of its most recent movement actionMOB
ENEMY_INATTACKSIGHT_INThe targeted player is within the creature's attack rangeMOB
ENEMY_OUTATTACKSIGHT_INThe targeted player is outside the creature's attack range (but within its area of interest)MOB
ENEMY_OUTSIGHT_INThe targeted player has left the creature's area of interestMOB
ENERGY_RECHARGED_INThe creature's power has replenished (?)MOB
FRIEND_ATTACKED_INAn allied creature was attacked in the creature's area of interestMOB
G_CHARACTER_ATTACKSIGHT_INA player entered the WOE guardian's attack range (?)MOB
G_CHARACTER_INSIGHT_INA player entered the WOE guardian's area of interest (?)MOB
ITEM_INSIGHT_INA lootable item was detected in the creature's area of interestMOB
LOWERLEVEL_INSIGHT_INA viable target (low level player?) has been detected in the creature's area of interestMOB
MAGIC_LOCKON_INA spellcast targeting the creature was detectedMOB
MILLI_ATTACKED_INThe creature was attacked (by a player?) in melee rangeMOB
MOVE_END_POS_INThe creature has arrived (after moving to a new location)MOB
MOVE_RANDOM_END_INThe random movement delay timer is about to be resetMOB
MOVE_START_INThe creature is about to start moving to a new locationMOB
MYOWNER_ATTACKED_INThe unit's parent unit was attackedMOB
MYOWNER_OUTSIGHT_INThe unit's parent has left the area of interestMOB
NEAREST_CHARACTER_INThe nearest player (or other unit?) has been updated for this creatureMOB
TARGET_ITEM_DISAPPEAR_INThe item that the creature was trying to loot has disappeared from the floorMOB
TOUCHED_INA player has moved on or directly adjacent to the NPCNPC
TOUCHED2_INA player or a party member has moved on or directly adjacent to the NPC (?)NPC
TOUCHEDNPC_INAnother NPC has moved on or directly adjacent to the NPC (?)NPC
WAIT_END_INThe random movement delay timer has elapsedMOB

Some of them are only used for "friendly" units, like vendors and quest NPCs. This is usually evident from the event description, but the additional "scope" field should help to make it even clearer. Such a distinction does not exist in the game, as all NPC actors can theoretically be assigned arbitrary events and states (though the resulting behavior might be undefined).

List of Output Events

These are ingame events emitted by the FSM when a state transition completes:

IDDescriptionScope
CALL_ARENASTART_OUTStarts an "arena" (PVP) event (?)NPC
CALL_CLICKEVENT_OUTTriggers the NPC's OnClick handlerNPC
CALL_TOUCHEVENT_OUTTriggers the NPC's OnTouch handler (NPC touched by player)NPC
CALL_TOUCHEVENT2_OUTTriggers the NPC's OnTouch2 handler (NPC touched by player or party member?)NPC
CALL_TOUCHNPCEVENT_OUTTriggers the NPC's OnTouchNPC handler (NPC touched by other NPC?)NPC
CHANGE_ENEMY_OUTAttempts to change targets (start scanning?)MOB
CHANGE_NORMALST_OUTRestores the default ("Idle") stateMOB
EXPEL_OUTStarts pursuing a target, outside of the creature's attack rangeMOB
MOVE_RANDOM_START_OUTStarts a new random walkMOB
MOVE_START_OUTStarts a (random?) walk, for NPCs only?NPC
MOVETO_ITEM_OUTStarts moving to the location of an item on the floorMOB
MOVETO_MYOWNER_OUTStarts moving to the parent unit (reduce distance?)MOB
NONE_OUTDoes nothing (dummy event?)MOB
PICKUP_ITEM_OUTMakes the creature loot an itemMOB
REVENGE_ENEMY_OUTStarts using attacks (and/or abilities?) on a hostile unit in attack range?MOB
REVENGE_RANDOM_OUTStarts using attacks (and/or abilities?) on a random hostile unit in attack range?MOB
SEARCH_OUTStarts scanning for targets in the area of interestMOB
STOP_AND_CLICKEVENT_OUTStops NPC movement, then triggers its OnClick handler?NPC
STOP_MOVE_OUTStops the current movement, discarding the pathMOB
TRADE_START_OUTOpens the vendor's trading window?NPC
TRY_REVIVAL_OUTAttempt to regenerate the creature (can this fail?)MOB
WAIT_START_OUTStarts the random walk delay timerMOB

AI Presets

All creatures in RO follow a simplistic routine that is derived from predefined configuration settings (the "AI presets"). These categorize monsters roughly by their intended approach to interacting with other actors in the game world, and are then enriched with specific ability usage patterns (the "skillsets") for each individual creature type to create additional depth.

Preset Swaps

Presets aren't fixed, but rather assigned. The implication is that creatures are free to change between archetypes if their custom logic so dictates. While this doesn't affect their skill usage, as skillsets are static and tied to the unit's class, it can make monsters prioritize targets differently or move in new ways. That's what happens when bosses "enrage", presumably.

List of AI Presets

There are at least 27 known behavior archetypes that form the basis of the AI system. A complete list is difficult to compile and somewhat out of scope, but Kokotewa's database shows the archetype for each creature if you feel like cross-referencing them.

Skill Usage

Skills are used according to a predefined behavior table for each creature type, based on the creature's current AI state and random chance, as well as certain conditions. Additionally, emotes and chat output can be triggered via this mechanism.

Skillsets

The logic for any creature's skill usage patterns is defined by the following information:

  • Creature ID: The unique identifier referring to the creature's unit class
  • Input State ID: One of the aforementioned AI state identifiers (e.g., IDLE_ST)
  • Skill ID: The unique identifier defining the skill to be used
  • Level: The level of the skill that should be cast
  • Chance: Probability for the creature to use the skill
  • Cast Time: Time before the cast is actually completed
  • Delay: Timeout for this trigger

These properties are mandatory and largely self-explanatory in their meaning. However, some optional properties also exist:

  • A flag indicating whether the cast can be interrupted (by damage or use of the Dispel ability)
  • An AI preset ID to swap to in response to the trigger, if any
  • A flag indicating whether emotes or chat messages should be sent
  • If emotes or chat are used: An identifier for the emoticon or chat message (taken from a predefined table)
  • A keyword for additional conditions that need to be fulfilled (e.g., "the number of minions is lower than X")
  • A conditional value that should be evaluated as part of the condition (that's the "X" part in this example)

Emotes

Emotes are triggered at the end of the cast. It's unknown whether they still trigger if the cast was interrupted.

Monster Talk

The RO client contains a "monster talk table" (data/monster_talk_table.xml), which stores the text that would be displayed as part of a creature's skillset. It seems that this feature is no longer in use, most likely because it's annoying. Although it's seen use on some private servers in the past, it's unclear whether AI-controlled messages were at some point enabled on official servers.

Conditional Keywords

Here's the list of all known special conditional keywords:

Keyword IDOperatorExpected ValueInterpretationExample Usage
IF_ALCHEMIST------Flag to enable alternate skillsets for summoned plantsMarine Sphere: Self Destruct
IF_COMRADECONDITION===Effect IDAllied creature is afflicted by status effectChepet: Status Recovery
IF_COMRADEHP<=NumberAllied creature is below health percentageAngeling: Heal
IF_ENEMYCOUNT>=NumberNumber of enemies in attack range is above thresholdAlarm: Splash Attack
IF_HIDING------Unit is hidden (Hiding skill)Smokie: Heal
IF_HP<=NumberUnit's health is below thresholdSohee: Suicide
IF_MAGICLOCKED------Unit's cast detection has triggeredAmon Ra: Summon Monster
IF_MASTERATTACKED------Parent unit was recently attacked (?)Summoned Hydra (Alchemist): Revenge
IF_MASTERHP<=NumberParent unit's health is below thresholdSummoned Geographer (Alchemist): Heal
IF_RANGEATTACKED------Unit was recently hit by a ranged attackErrende Ebecee (BioLabs Acolyte): Pneuma
IF_RUDEATTACK------Unit was hit, but cannot retaliate (no path to attacker available?)Every creature: Teleport
IF_SKILLUSE===Skill IDUnit was hit by skill (must be damaging?)Eddga: Fireball (when hit by Fire Wall damage)
IF_SLAVENUM<=NumberNumber of minions alive is below thresholdGarm: Summon Slave
IF_TRICKCASTING------No idea (placeholder?)Marine Sphere: Speed Up

Examples

The following screenshot of ANGELING's skillset (taken from Kokotewa's RO database) illustrates the format well:

Screenshot of the skillset table for ANGELING

Accordingly, its skill usage pattern for Summon Slave can be summed up in a few sentences:

Angeling has a 100% chance to summon new followers, when it's attacking or idle and the number of existing minions is three or less. This cast takes 2 seconds, is not interruptible, and can only be used once per minute. It will emote /heh afterwards.

A similar interpretation of any other skill trigger is possible. In combination, they fully define the entire skillset.