From DSP Wiki
Jump to: navigation, search

Referred to as the "Core", this is the main C++ codebase. It is split into different sections which will be outlined here. Please note that this may not always remain in date as new things are added. The main beef of the server code will be outlined here, but not the extreme odd cases which are never used (e.g. /common/ or /items/ folders).

Map Server (aka Game Server)

The Map Server is the main server which governs how the game is played. It is REQUIRED in order for the server to work. The Connect Server is also required in order for characters to connect to the Map Server. The Search Server is optional. The following subsections breaks down the map server based on where it is physically located folder-wise.

Entity AI (/src/map/ai)

This governs how the server should respond to given actions. These actions are on a high-level, e.g. attacking, disengaging, using TP moves, using items, etc. You can treat this AI as a primitive state system, whereby you can be in the "Attack" state, "Roaming" state, and so on.

All Entities

  • ActionAttack : Logic when attacking, including delay, calculation of damage, hit rate, counters, paralyze, intimidation, you name it.
  • ActionNone : No logic at all (e.g. a mob that has despawned may be in this state, or a deallocated entity).
  • ActionEngage : When you engage, these checks are performed. Usually transfers straight into ActionAttack after calling lua scripts. For monsters, you engage on aggro/turning red only.
  • ActionDisengage : Logic that occurs when you disengage.
  • ActionFall : Logic when you transfer from being alive to being dead, the transition to the Death state.
  • ActionDeath : Logic when you're dead, usually maintenance tasks like removing yourself from the entity pool.


  • ActionMagicStart : Checks to perform when beginning to cast a spell, you can say things like "Not enough MP" or "You must have a pet" here.
  • ActionMagicCasting : Checks to perform whilst mid-cast, this also checks to see if you are past the cast time for the spell where it will go into ActionMagicFinish.
  • ActionMagicFinish : Checks to perform when finishing casting (spell interruption from movement), including calling the lua scripts for spells.
  • ActionMagicInterrupt : When you have been interrupted, this is the state you enter.
  • Action


  • ActionDropItems : Drops items, including calculating the probability of drops, assigning them to the treasure pool, etc.
  • ActionFadeOut : Fades the monster out after death.
  • ActionMobAbilityStart : Checks to perform when starting a TP ability e.g. selection of a TP move
  • ActionMobAbilityUsing : Checks to perform whilst using a TP ability e.g. check for Stun and if so, interrupt the move.
  • ActionMobAbilityInterrupt : The state to go into when interrupted.
  • ActionMobAbilityFinish : Checks to perform when the TP ability finishes, including calling lua scripts.
  • ActionRoaming : Manages the idle state, including moving around.
  • ActionSpawn : Checks to perform on spawn.
  • ActionSleep : Checks to perform when slept (usually the checks are to see if you can wake up).


  • ActionMobAbilityStart : Checks to perform when starting a TP ability e.g. selection of a TP move
  • ActionMobAbilityUsing : Checks to perform whilst using a TP ability e.g. check for Stun and if so, interrupt the move.
  • ActionMobAbilityInterrupt : The state to go into when interrupted.
  • ActionMobAbilityFinish : Checks to perform when the TP ability finishes, including calling lua scripts.

LUA (/src/map/lua)

This provides the main interface between scripting land and C++ land. If scripters need some awesome thing in the core added to LUA, this is where you add it. This is split into several different sections, all of which are very different, so check out the dedicated LUA section for more info.

LUA (Core)


This defines the packet structures that will be sent to the client. If an update breaks FFXI, this is where you have to go to fix it (because the packet strucutres have changed!).

Other (/src/map)

This contains everything else, which is actually quite a lot. It can be broadly grouped into these categories:

* Entities (NPC,Pet,Char,Mob)
* Instances (BCNMs)
* Items (Armor, Weapons, Consumables, etc)
* Effects (Modifiers and Status Effects)
* Zone (handling of everything in the zone)
* Synthesis
* Parties
* Linkshells
* Time management
* Enmity

Search Server

The Search Server was designed to take a lot of the heavy lifting search stuff away from the main server. If you were to do these searches on the main server, the game would grind to a halt and stop working, primarily because the server would be too busy doing SQL queries and not handling incoming packets. Its primary focus is on searching and the auction house.


Requests filter through (eventually) to TCPComm in search.cpp. Each request has a unique packet request ID which indicates if it is searching all areas, a single area, etc. Normal searches all go to the same function HandleSearchRequest. This populates a search_req struct with information on the search request (jobs specified, level ranges, zones, etc). This is then fed into the data_loader which does the actual SQL query to get the results. This then comes back as a list of SearchEntities. These can then be populated (with the 20 cap enforced) into a SearchPacket which is then sent back.

A variant of this is the GroupListRequest, which is requested when you view your party or view your linkshell members. This functions in very much the same way, but only needs the party ID or linkshell ID from the request in order to do a database search.

Auction House

Requests filter through (eventually) to TCPComm in search.cpp. Each request has a unique packet request ID which indicates if it is for the auction house. If it is, it can either be for a list of items based on category (HandleAuctionHouseRequest) or an in-depth view of the buyers/sellers of a single item (HandleAuctionHouseHistoru). The player's personal list of items up for auction SHOULD be here as well but currently is not.

Connect Server (aka Lobby Server)

The Lobby Server is a magical server whereby almost certainly a wizard did it. It consists of three distinct sub-servers (for some reason) which don't always get along. This is the least documented server and one of the more obfuscated ones. The three processes are discussed below (but not in that much detail)


Seems to handle the initial connection with the client, including registering new accounts. (login_auth.cpp)


Seems to be the glue between the other two sections (read: this part falls over a lot). It handles creating/deleting characters, setting the bitmask of the expansions, etc.


Seems to handle loading of the character list for this account, and displaying that to the user.


The database manages all of the information which can fall neatly into categories, like item data, weapon data, character data, auction house data, spell data and so on. Most of these tables are self-explanatory but some are not. The tables which are ambiguous or otherwise complete gibberish are hopefully demystified below.


  • Ability ID : The unique ID assigned by the client for this ability. Find these values in ROM/181/72 (or String Tables > English > Ability Names in POLUtils). These IDs are 528 offset, so you must SUBTRACT 528 from the "index" field in POLUtils.
  • Job : The unique Job ID assigned by the client. This is the same as for scripting, so WAR=1 MNK=2 WHM=3 ...
  • validTarget : This is a bitmask of the valid targets, given by the enum in battleentity.h
     TARGET_SELF            = 0x01,
     TARGET_PLAYER_PARTY    = 0x02,
     TARGET_ENEMY           = 0x04,
     TARGET_PLAYER          = 0x10,
     TARGET_PLAYER_DEAD     = 0x20,
     TARGET_NPC             = 0x40
 // Visually:
 // 0   0   0   0   0   0   0
 //e.g. 3 is Self and Player Party. 4 is Enemy only. etc.
  • recastId : The recast ID for this ability, I think the recast plugin on Windower has the IDs for this in their XML files?
  • animation : The animation ID to use for this ability. This has to be wizarded via packet captures or trial and error, I don't think this can be obtained automatically.


  • bcnmId : Arbitrary ID to indicate a unique BCNM. Not tied to the client in any way.
  • rules : The rules to apply to this BCNM (not fully implemented in the core). This is also a bitmask which is as follows (from the .sql comments)
rules format (bits): 0000 0 0 0 0 = E D C B A
A = allow SJs (1 if yes)
B = lose exp on death (1 if yes)
C = all dead rules (0=remove immediately, 1=remove after 3 min)
D = spawn trasure chest on win (1 if yes)
E = reserved
e.g. 00000100 = no sjs, no exp loss, remove player after 3mins = 4

BCNM Instance

  • instanceNumber : The instance number is between 1-3 for pretty much every BCNM. There are three copies of the bcnm area in a zone. The client(!) seems to know which copy is instance 1, which is instance 2, etc, so it can be hard to know which monster ID should go with which instance ID without hacking it (changing bcnm.lua code).

Mob Family System

  • STR DEX ... : This is the RANK of the chosen stat in numerical form (1 being A rank).

Mob Groups

  • spawntype : This is a bitmask of when the monster can spawn, given by the following:
     SPAWNTYPE_NORMAL        = 0x00, // 00:00-24:00
     SPAWNTYPE_ATNIGHT       = 0x01, // 20:00-04:00
     SPAWNTYPE_ATEVENING     = 0x02, // 18:00-06:00
     SPAWNTYPE_WEATHER       = 0x04, 
     SPAWNTYPE_FOG           = 0x08, // 02:00-07:00
     SPAWNTYPE_MOONPHASE     = 0x10,
     SPAWNTYPE_LOTTERY       = 0x20,
     SPAWNTYPE_WINDOWED      = 0x40,
     SPAWNTYPE_SCRIPTED      = 0x80

Mob Pools

  • modelid : This is the unique model ID that this monster represents. This has to be captured from packet 0x0e.
  • behavior : This is a lovely mis-spelling of 'behaviour'. It is also a bitmask which represents how the monster should behave:
     BEHAVIOUR_NONE              = 0x00,
     BEHAVIOUR_AGGRO_SIGHT       = 0x01,
     BEHAVIOUR_AGGRO_LOWHP       = 0x04,
     BEHAVIOUR_AGGRO_MAGIC       = 0x20,


  • links : Simple boolean, 1 if true, 0 otherwise.
  • mobType : Yet another bitmask which governs the type(s) the monster falls under:
     MOBTYPE_NORMAL      = 0x00,
     MOBTYPE_PCSPAWNED   = 0x01,
     MOBTYPE_NOTORIOUS   = 0x02,
     MOBTYPE_FISHED      = 0x04,
     MOBTYPE_CALLED      = 0x08,
     MOBTYPE_EVENT       = 0x20
  • namePrefix : 0 for no special prefix ("the" monster). 32 and 64 are for special prefixes (e.g. Seiryu which has no "the" before it). These are packet captured so see Packets/0x0e.
  • flag : Packet captured value of the flag(s) for this monster. Most of these have been discovered, see Packets/0x0e.
  • unknown : Packet captured value. See Packets/0x0e.

Mob Skill

  • mob_skill_id : The unique ID that governs this monsters skill. This can be found in trunk/documentation/mob_tp_movies.txt or via the DATs.
  • mob_anim_id : The unique animation ID that represents this skill. This is found by trial and error or via packet capturing.
  • mob_skill_aoe : 0 for non-aoe, 1 for AoE around SELF(monster), 2 for AoE around TARGET(think bomb toss), 4 for conal AoE (not-implemented),

NPC List

Pet List

  • petid : Arbitrary ID to define a pet.

Status Effects

  • id : Client-side ID to represent the status (used for icons in some cases). Find these in String Tables > English > Status Names or ROM/180/102.dat
  • flags : Bitmask of one or more of:
     EFFECTFLAG_NONE             = 0x0000,
     EFFECTFLAG_DISPELABLE       = 0x0001,
     EFFECTFLAG_ERASABLE         = 0x0002,
     EFFECTFLAG_ATTACK           = 0x0004,
     EFFECTFLAG_DAMAGE           = 0x0010,
     EFFECTFLAG_DEATH            = 0x0020,
     EFFECTFLAG_MAGIC_BEGIN      = 0x0040,
     EFFECTFLAG_MAGIC_END        = 0x0080,
     EFFECTFLAG_ON_ZONE          = 0x0100,
     EFFECTFLAG_NO_LOSS_MESSAGE  = 0x0200, // Suppress effect worn off message.



  • traitid : The unique client-side trait ID. Find these values in ROM/181/72 (or String Tables > English > Ability Names in POLUtils and go waaay down to 385+). These are 384 offset, so you must SUBTRACT 384 from the "index" field in POLUtils to get these values.

Special Case: Avatar BPs

  • Avatar Blood Pacts use fields differently in order to get the required information. The two tables that need to be edited are abilities.sql and mob_skills.sql.
  • abilities.sql - The animation field is actually the MP cost.
  • abilities.sql - The recast ID is either 173 or 174 for BP:Rage or BP:Ward
  • abilities.sql - The ability ID is found in POLUtils (String Tables > English > Ability Names). It is the index in POLUtils - 16.
  • mob_skills.sql - The family ID is the ID of the family of monsters (duh, so Avatar-Titan, Avatar-Garuda, etc).
  • mob_skills.sql - The mob_skill_id is found in monster_tp_movies.txt in /documentation/
  • mob_skills.sql - The mob_anim_time is actually the related ability ID (so Whispering Wind should be 578 as the ability ID for it is that).
  • mob_skills.sql - The mob_anim_id is the hard one and has to be packet captured or got via trial and error. The other avatar anim_ids are close in value to the current ones.

Flow of Control

Possibly the most important thing to understand is how the server (map server in particular) actually works in terms of actual work performed based on a given input. Several examples will be examined to see how the server flows through the files mentioned above to get to the packet to send back. See Server Data Flow.