Skip to main content

High-level overview

LandSandBoat is composed of four cooperating server processes, a shared C++ library (common/), and a Lua scripting layer that runs inside the map process. All inter-process communication uses ZeroMQ.
┌──────────────────────────────────────────────────────────────┐
│                         CLIENTS                              │
│                    (FFXI game client)                        │
└───────────────┬──────────────────────────────────────────────┘
                │ TCP port 54001
┌───────────────▼──────────┐
│       xi_connect          │  Client auth, session routing
│       (src/login/)        │
└───────────────┬──────────┘
                │ ZMQ (IPC)
     ┌──────────▼──────────┐        ┌──────────────────────────┐
     │      xi_world        │◄──────►│       xi_search           │
     │    (src/world/)      │  ZMQ   │      (src/search/)        │
     │  HTTP API :8088      │        │      TCP port 54002       │
     └──────────┬──────────┘        └──────────────────────────┘
                │ ZMQ (IPC)
     ┌──────────▼──────────┐
     │   xi_map (×N)        │  Zones, entities, combat, Lua
     │    (src/map/)        │  UDP ports 54230, 54231, ...
     └─────────────────────┘

     ┌──────────▼──────────┐
     │   Lua scripts        │  scripts/ directory
     │   (sol2 bindings)    │
     └─────────────────────┘

Source directory structure

src/
├── common/          # Shared library: database, logging, IPC, ZMQ wrappers, settings
├── login/           # xi_connect process (client authentication)
├── search/          # xi_search process (auction house, /search)
├── world/           # xi_world process (global state, HTTP API, IPC routing)
├── map/             # xi_map process (zones, entities, combat, Lua engine)
│   ├── lua/         # Lua binding layer (sol2-based)
│   ├── ai/          # AI state machines
│   ├── entities/    # Entity types (char, mob, npc, pet, trust, etc.)
│   ├── packets/     # Packet definitions
│   └── utils/       # Battle, char, and other utilities
└── test/            # xi_test process and Lua test framework

The four processes

Handles client TCP connections on port 54001. Responsible for:
  • Client version verification and authentication
  • Session establishment and initial data transfer
  • Routing authenticated sessions to the correct xi_map instance
Key files: connect_application.cpp, connect_engine.cpp, auth_session.cpp, data_session.cpp
The central coordination process. Exposes an HTTP API on port 8088 and a ZMQ router that all xi_map instances connect to. Responsible for:
  • Routing IPC messages between map processes (chat, party, alliance, linkshell, etc.)
  • Managing global game state: conquest, besieged, campaign, colonization
  • Maintaining the character cache and zone-to-process routing table
  • Serving the HTTP management API (HTTPServer)
Key files: world_engine.cpp, ipc_server.cpp, http_server.cpp, character_cache.cpp
The largest process — one or more instances, each handling a subset of zones. Responsible for:
  • Running all zone logic, entity simulation, and combat
  • Executing Lua scripts via the sol2 binding layer
  • Accepting game client UDP traffic on ports 54230 and 54231 (configurable)
  • Communicating with xi_world via ZMQ for cross-zone and cross-process events
Key files: map_engine.cpp, map_networking.cpp, zone.cpp, ipc_client.cpp

C++ core and Lua scripting layer

The C++ core handles all performance-critical game logic: networking, entity simulation, combat calculations, packet encoding, and database access. Lua scripts in the scripts/ directory are loaded at runtime and handle game content: NPC dialogue, quests, mob behavior, spells, and zones. The boundary between C++ and Lua is managed by the sol2 library. Every game object type that Lua scripts need to interact with has a corresponding CLua* wrapper class in src/map/lua/ (e.g., CLuaBaseEntity, CLuaZone, CLuaSpell). C++ calls Lua event callbacks via the luautils namespace. See Lua/C++ bindings for the full binding reference.

IPC (inter-process communication)

All four processes share the IPC message definitions in src/common/ipc_structs.h. Messages are serialized to byte arrays and routed over ZMQ:
  • xi_world runs a ZMQ ROUTER socket — it acts as the central message broker
  • xi_map instances each run a ZMQ DEALER socket and connect to xi_world
  • xi_connect and xi_search also connect to xi_world for session events
Message handlers are declared via ipc::IPCMessageHandlerBase<T> in src/common/ipc.h, with concrete implementations in IPCServer (world) and IPCClient (map).

common/ shared library

The src/common/ directory is a shared static library compiled into all four processes:
FilePurpose
application.h/cppBase class for all process applications
engine.h/cppBase class for all process engines
database.h/cppMariaDB connection and query helpers
logging.h/cppSpdlog-based structured logging
settings.h/cppSettings file loader (reads settings/*.lua)
lua.h/cppGlobal sol::state lua declaration
ipc.h, ipc_structs.hIPC message types and handler base
zmq_dealer_wrapper.hZMQ DEALER socket wrapper
zmq_router_wrapper.hZMQ ROUTER socket wrapper
scheduler.hCoroutine-based task scheduler
timer.h, vana_time.hGame time and real-time utilities
xirand.h/cppRandom number generator

Build docs developers (and LLMs) love