Skip to main content

Process overview

ProcessBinaryPrimary port(s)ProtocolSource
xi_connectxi_connect54001TCPsrc/login/
xi_searchxi_search54002TCPsrc/search/
xi_worldxi_world8088 (HTTP)HTTP + ZMQsrc/world/
xi_mapxi_map54230, 54231, …UDP + ZMQsrc/map/

Startup order

xi_world must be running before xi_map starts, because each xi_map instance connects to the world’s ZMQ ROUTER on startup to register its zone endpoints. Recommended order:
  1. database (MariaDB)
  2. xi_connect
  3. xi_search
  4. xi_world
  5. xi_map (one or more instances)
This matches the depends_on ordering in dev.docker-compose.yml:
map:
  depends_on:
    database:
      condition: service_healthy
    world:
      condition: service_started
    connect:
      condition: service_started
    search:
      condition: service_started

xi_connect

Source: src/login/ | Port: 54001 (TCP) xi_connect is the first process that a game client contacts. It handles the login protocol and session bootstrapping before routing the player to the correct xi_map instance.

Responsibilities

  • Authentication: Validates account credentials against the accounts table
  • Session setup: Establishes the initial data session and transfers character list and world data
  • Client version check: Verified against the CLIENT_VER setting in settings/login.lua
  • Port routing: Sends the client the IP and port of the xi_map process that owns the player’s target zone
  • OTP support: Optional one-time-password authentication (otp_helpers.h)

Key files

FileDescription
connect_application.cppApplication entry point
connect_engine.cppMain engine loop
auth_session.cppAccount authentication session
data_session.cppCharacter and world data transfer
view_session.cppCharacter select screen handling
handler_session.cppGeneric session handler base
login_helpers.cppShared login utility functions
Source: src/search/ | Port: 54002 (TCP) xi_search handles player /search queries and auction house browsing. It is a lightweight, read-heavy process that queries the database directly.

Responsibilities

  • Player search: Responds to /search commands with player locations, job, and level
  • Auction house: Serves item listings, prices, and history to clients
  • Data loading: Periodically refreshes player location data from the database

Key files

FileDescription
search_application.cppApplication entry point
search_engine.cppMain engine loop
search_handler.cppRequest handler for search and AH packets
data_loader.cppDatabase data loader

xi_world

Source: src/world/ | Port: 8088 (HTTP) xi_world is the coordination hub. It does not handle game clients directly — instead, it routes IPC messages between all xi_map instances and manages global game state that spans multiple zones.

Responsibilities

  • IPC routing: Acts as a ZMQ ROUTER, forwarding messages between xi_map processes (chat, party, alliance, linkshell, etc.)
  • Global systems: Conquest, besieged, campaign, colonization tallying
  • Character cache: Tracks which zone/process each online character is in
  • HTTP API: Exposes a management API on port 8088 (player counts, zone population)
  • Time server: Drives Vana’diel time, game day/hour events

HTTP API endpoints

The HTTP server (src/world/http_server.cpp) exposes live session data:
  • Active session count
  • Active unique IP count
  • Per-zone player counts (indexed by zone ID up to ZONEID::MAX_ZONEID)

Key files

FileDescription
world_application.cppApplication entry point
world_engine.cppMain engine loop
ipc_server.cppZMQ ROUTER message handler
http_server.cppHTTP management API
character_cache.cppCross-zone character tracking
conquest_system.cppConquest tally logic
besieged_system.cppBesieged event management
time_server.cppVana’diel clock and day/hour events

xi_map

Source: src/map/ | Ports: 54230, 54231, … (UDP) xi_map is the largest process and handles all in-zone gameplay. Multiple instances can run simultaneously, each owning a different set of zones. Zone-to-process assignment is stored in the zone_settings database table (zoneport column).

Responsibilities

  • Zone management: Loads and ticks all zones assigned to this process
  • Entity simulation: Characters, NPCs, mobs, pets, trusts, and fellowship NPCs
  • Combat engine: Melee, ranged, magic, weapon skills, mob skills, pet abilities
  • Lua scripting: Loads and executes all scripts/ content via the sol2 binding layer
  • Packet handling: Encodes and decodes all in-zone game packets
  • IPC client: Connects to xi_world as a ZMQ DEALER for cross-zone messaging

Multi-process configuration

Zones can be distributed across multiple xi_map instances using dbtool’s configuration commands:
# Single process (all zones on port 54230)
python tools/dbtool.py  # then select Maintenance Tasks → Configure single-process

# 3-process split (zones distributed by zone ID modulo 3)
# Ports: 54230, 54231, 54232

# 7-process split
# Ports: 54230, 54231, ..., 54236

Key files

FileDescription
map_application.cppApplication entry point
map_engine.cppMain engine loop and zone tick orchestration
map_networking.cppUDP packet I/O
ipc_client.cppZMQ DEALER connecting to xi_world
zone.cppZone class — entities, ticks, spawning
zone_entities.cppEntity container and iteration
lua/luautils.cppLua event dispatch functions
ai/AI state machines for mobs, NPCs, etc.
entities/Entity class hierarchy

Port reference

PortProcessProtocolDescription
3306databaseTCPMariaDB
54001xi_connectTCPClient login
54002xi_searchTCPPlayer search / auction house
8088xi_worldHTTPManagement API
54230xi_mapUDPZone game traffic (default, process 0)
54231xi_mapUDPZone game traffic (process 1, if multi-process)
Port 54230 and 54231 are also listed as TCP on xi_connect in the dev Docker Compose because the connect process proxies zone connection info to clients. The actual in-zone game traffic from clients is UDP to xi_map.

Build docs developers (and LLMs) love