Process overview
| Process | Binary | Primary port(s) | Protocol | Source |
|---|
| xi_connect | xi_connect | 54001 | TCP | src/login/ |
| xi_search | xi_search | 54002 | TCP | src/search/ |
| xi_world | xi_world | 8088 (HTTP) | HTTP + ZMQ | src/world/ |
| xi_map | xi_map | 54230, 54231, … | UDP + ZMQ | src/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:
database (MariaDB)
xi_connect
xi_search
xi_world
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
| File | Description |
|---|
connect_application.cpp | Application entry point |
connect_engine.cpp | Main engine loop |
auth_session.cpp | Account authentication session |
data_session.cpp | Character and world data transfer |
view_session.cpp | Character select screen handling |
handler_session.cpp | Generic session handler base |
login_helpers.cpp | Shared login utility functions |
xi_search
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
| File | Description |
|---|
search_application.cpp | Application entry point |
search_engine.cpp | Main engine loop |
search_handler.cpp | Request handler for search and AH packets |
data_loader.cpp | Database 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
| File | Description |
|---|
world_application.cpp | Application entry point |
world_engine.cpp | Main engine loop |
ipc_server.cpp | ZMQ ROUTER message handler |
http_server.cpp | HTTP management API |
character_cache.cpp | Cross-zone character tracking |
conquest_system.cpp | Conquest tally logic |
besieged_system.cpp | Besieged event management |
time_server.cpp | Vana’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
| File | Description |
|---|
map_application.cpp | Application entry point |
map_engine.cpp | Main engine loop and zone tick orchestration |
map_networking.cpp | UDP packet I/O |
ipc_client.cpp | ZMQ DEALER connecting to xi_world |
zone.cpp | Zone class — entities, ticks, spawning |
zone_entities.cpp | Entity container and iteration |
lua/luautils.cpp | Lua event dispatch functions |
ai/ | AI state machines for mobs, NPCs, etc. |
entities/ | Entity class hierarchy |
Port reference
| Port | Process | Protocol | Description |
|---|
| 3306 | database | TCP | MariaDB |
| 54001 | xi_connect | TCP | Client login |
| 54002 | xi_search | TCP | Player search / auction house |
| 8088 | xi_world | HTTP | Management API |
| 54230 | xi_map | UDP | Zone game traffic (default, process 0) |
| 54231 | xi_map | UDP | Zone 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.