Architecture

Hexagonal Architecture

firelands-next implements Hexagonal Architecture (Ports & Adapters). Business rules live at the center; databases, sockets, Lua, and DBC files plug in through interfaces. The client target is WoW Cataclysm 4.3.4 (build 15595).

Core Definitions

TermMeaning in Firelands
PortAbstract interface the core depends on (e.g. ICharacterRepository, IGameScriptHost). Domain and application layers define ports; infrastructure implements them.
AdapterConcrete implementation of a port (e.g. MySqlCharacterRepository, LuaGameScriptHost). Lives in infrastructure/.
EntityMutable object with identity and lifecycle (e.g. Player, Creature, Character).
Value ObjectImmutable data without identity (e.g. coordinates, spell cooldown snapshots, GUID wrappers).
Use Case / ServiceApplication-layer orchestration (e.g. CharacterService, CommandService) that coordinates domain objects through ports.
Composition RootExecutable entry point (auth, world) that wires concrete adapters to ports at startup.
RepositoryPort for persistence; domain declares I*Repository, infrastructure provides MySql*.

Layer Structure

src/
├── shared/           # FirelandsShared — config, logging, crypto, DBC, wire formats
├── domain/           # FirelandsDomain — entities, world model, combat, repository ports
├── application/      # FirelandsApplication — use cases, services, application ports
├── infrastructure/   # FirelandsInfrastructure — MySQL, ASIO, Lua, DBC stores, REST
├── auth/             # Auth server composition root
├── world/            # World server composition root
└── tools/            # FirelandsDevTools CLI

CMake link order: FirelandsSharedFirelandsDomainFirelandsApplicationFirelandsInfrastructure → executables.

Dependency Rule

  • domain/ must not import from application/ or infrastructure/.
  • application/ depends on domain/ + shared/ only — no concrete MySQL or Boost.Asio headers.
  • External dependencies flow inward: Infrastructure → Application → Domain → Shared.
  • Communication across boundaries uses abstract ports, injected at startup in auth/main.cpp and world/main.cpp.

Shared Layer (FirelandsShared)

Lowest library; no game services or persistence. Add code here only when multiple layers need it and it has no MariaDB/ASIO dependency.

AreaPathPurpose
Configshared/Config.{h,cpp}YAML loading (authserver.yaml, worldserver.yaml); env overrides FIRELANDS_AUTH_CONFIG / FIRELANDS_WORLD_CONFIG
Loggingshared/Logger.hspdlog wrapper; always include via this header for SPDLOG_LEVEL_NAMES
Crypto / SRPshared/Crypto.h, SRPConstants.h, BigInt.hSRP-6a math for authentication
Networkingshared/network/ByteBuffer, WorldPacket, opcodes (WorldOpcodes.h), wire codecs (SpellCastWire, gossip packets), WorldCrypt.h
DBCshared/dbc/DbcReader.cppClient .dbc-style binary table reader
Game helpersshared/game/Access levels, permissions, GM appearance, experience tables
TUIshared/tui/FTXUI helpers for interactive consoles

Domain Layer (FirelandsDomain)

Models what the emulator manipulates — not how data is stored or packets are sent.

World entities (domain/world/)

TypeFileRole
WorldObjectWorldObject.hBase: GUID, MovementInfo position
PlayerPlayer.{h,cpp}Live health/power, auras, map notifications
CreatureCreature.{h,cpp}NPC entry, faction, flags, combat XP
GameObjectGameObject.{h,cpp}World object placement
MapMap.{h,cpp}Object grid / spatial indexing
AuraAura.h, UnitAuraState.*Buff/debuff state on units

Account / data models (domain/models/)

Character, Realm, PlayerCreateInfo, GmTicket, GossipMenu, NpcText, QuestGossip, SpellDefinition, WebSession, Chat, and Account (via IAccountRepository.h).

Combat domain (domain/combat/)

ComponentRole
CombatEngineCore combat resolution
DamageCalculatorDamage formulas
ICombatEntityCombat-capable entity contract
IThreatManagerThreat table port
ISpellProcessorSpell processing port

Repository ports (domain/repositories/)

PortPurpose
IAccountRepositoryAccounts, SRP verifiers, session keys
IRealmRepositoryRealm list rows
ICharacterRepositoryCharacter CRUD and online state
IPlayerCreateInfoRepositoryStarter positions, spells, skills
IWebSessionRepositoryREST session tracking
IGmTicketRepositoryGM help tickets
IGossipRepositoryGossip menu data
INpcTextRepositoryNPC dialog text
IQuestGossipRepositoryQuest gossip lines
ICreatureSpawnRepositoryCreature spawn rows
ICreatureClassLevelStatsRepositoryNPC level stats
INpcTemplateSearchRepository.npc search template lookup
ISpellDefinitionStoreSpell metadata
ISpellCastTablesCast-time / power cost tables

Application Layer (FirelandsApplication)

Use cases and orchestration without knowing MariaDB or socket details.

Services (application/services/)

ServiceRole
AuthServiceAccount lookup, SRP verification, session keys
SRPServiceSRP-6a verification helpers
CharacterServiceCharacter list and persistence
PlayerCreateInfoServiceCharacter creation templates
RealmListServiceRealm list + live population via IRealmLiveState
WorldServiceRuntime world façade: maps, players, creatures, Lua host, collision port
CommandServiceStaff . commands and console dispatch
GmTicketServiceTicket queue, assignment, replies
OnlineCharacterSessionRegistryOnline name → session for console targeting
WebSessionServiceREST login/session flows

Spell & combat (application/spell/, application/combat/)

SpellManager and spell effect modules; CombatService, hostility, chase logic.

Application ports (application/ports/)

PortImplemented by
INetworkServerAsyncNetworkServer
IAuthSessionAuthSession
ICommandService / ICommandSessionCommandService / WorldSession
IGameScriptHostLuaGameScriptHost
IMapCollisionQueriesMapCollisionQueriesStub (vmap planned)
IMapNotifierMap/player update notifications
IRealmLiveStateRealmLiveRegistry + realm-link

Infrastructure Layer (FirelandsInfrastructure)

Wires the emulator to the outside world. All socket I/O uses C++20 coroutines (co_await, boost::asio::use_awaitable).

Persistence (infrastructure/persistence/)

AdapterPort
DatabaseMigratorRuns sql/bundled/sql/init/sql/migrations/; tracks schema_migrations
MySqlAccountRepositoryIAccountRepository
MySqlRealmRepositoryIRealmRepository
MySqlCharacterRepositoryICharacterRepository
MySqlPlayerCreateInfoRepositoryIPlayerCreateInfoRepository
MySqlGmTicketRepositoryIGmTicketRepository
MySqlGossipRepository, MySqlNpcTextRepository, MySqlQuestGossipRepositoryGossip ports
MySqlCreatureSpawnRepository, MySqlCreatureClassLevelStatsRepositorySpawn/stats
MemoryWebSessionRepositoryIWebSessionRepository (in-memory)
InMemoryThreatManager, MySqlThreatManager, MySqlSpellProcessorCombat ports

Network (infrastructure/network/)

ComponentRole
AsyncNetworkServerCoroutine accept loop; Update() polls io_context
AuthSessionAuth client read/write loops
WorldSessionWorld client; split handlers under worldsession/*.cpp
RestAuthServerREST login on Network.RestPort
RealmLinkSession / RealmLinkOutboundAuth ↔ world live realm metrics

Other adapters

ComponentRole
LuaGameScriptHostLua 5.4 scripting under Scripting.ScriptsDirectory
SpellEntryDbcStore, SpellCastTablesDbcClient DBC spell data
MapCollisionQueriesStubPlaceholder until full vmap integration

Executables (Composition Roots)

TargetBinaryStartup summary
authbuild/bin/authLoad authserver.yaml → migrate DB → wire MySQL repos → start auth TCP (3724), optional realm-link + REST (8081)
worldbuild/bin/worldLoad worldserver.yaml → init Lua + fire world_startup → migrate DB → connect auth/characters/world DBs → start world TCP (8085) + interactive console
FirelandsDevToolsbuild/bin/FirelandsDevToolsCLI for accounts and realm management

Operational flow: clients authenticate on auth (SRP-6a, realm list), then connect to world with session-derived crypto. Realm-link syncs live population/load from world to auth when configured.

Wire Format

Packet layouts and opcodes target WoW Cataclysm 4.3.4 (build 15595). Shared builders live under src/shared/network/ (e.g. SpellCooldownWire, KnownSpellsWire, gossip packets). ByteBuffer uses C++20 std::span helpers for safe reads and writes. WorldSession handlers are split by concern: movement, spells, gossip, GM state, tickets, object updates.

Precompiled Headers (PCH)

Heavy headers precompiled for faster builds: STL containers, spdlog, nlohmann/json, shared/Common.h, shared/Logger.h. When adding targets:

target_precompile_headers(<target_name> PRIVATE ${PROJECT_PCH_HEADERS})

Important: spdlog MUST be included via <shared/Logger.h>. LuaGameScriptHost.cpp skips PCH for toolchain compatibility.

C++ Conventions

RuleDetail
StandardC++20 (std::filesystem, std::optional, std::variant, std::span, coroutines in network code)
Namingsnake_case functions/variables; PascalCase types; UPPER_SNAKE_CASE constants; kebab-case file names
LanguageEnglish only for code, comments, and commits
WoW termsUse Blizzard nomenclature: Aura, Unit, SpellEffect, etc.
LoggingAlways via <shared/Logger.h>
Threadingstd::thread in business code
Commitstype(scope): description — types: feat, fix, refactor, docs, test, chore, perf
TDDRed → Green → Refactor for all new behavior

Architectural Diagram

Overview of composition roots, hexagonal layers, and external systems. Arrows show runtime wiring; dotted lines show the dependency rule (each layer depends only on layers below it — domain never imports infrastructure).

FirelandsShared

FirelandsDomain — business core

FirelandsApplication

FirelandsInfrastructure — adapters

Composition roots

External systems

SRP login realm list

game session packets

realm-link live metrics

uses

uses

uses

WoW Client Cataclysm 4.3.4

MySQL / MariaDB

DBC extracts and Lua scripts

auth — TCP 3724 REST optional

world — TCP 8085 console

FirelandsDevTools CLI

AsyncNetworkServer AuthSession WorldSession RealmLink

MySql repositories DatabaseMigrator

LuaGameScriptHost

SpellEntryDbcStore collision stub

Services Auth Character World Command GmTicket...

Ports INetworkServer IGameScriptHost IMapCollisionQueries...

Entities Player Creature Map models...

Repository ports ICharacterRepository IAccountRepository...

CombatEngine DamageCalculator threat spell ports

Config Logger Crypto ByteBuffer opcodes DbcReader

CMake link order (libraries): FirelandsSharedFirelandsDomainFirelandsApplicationFirelandsInfrastructureauth / world / FirelandsDevTools.