WoW Files Setup sheet
Stable branch WF Core · Pandaria Build 5.4.8

Mists of Pandaria setup

5.0.4 — 5.4.8

A longer compile and a much longer extraction. Budget an afternoon the first time, then it is routine.

Core branch
5.4.8
Protocol build
5.4.8 · build 18414
Client required
5.4.8 (18414)
Max level
90
Disk
150 GB
Build time
≈ 1 h 10 min

Before you start

Everything below assumes a clean host
  • A 5.4.8 (18414) clientExtraction reads your own legally obtained install. No client files ship with any core.
  • Roughly 150 GB freeExtracted maps, vmaps, and mmaps dwarf the core itself. Check before you start.
  • GCC 12+ · CMake 3.16+ · Boost 1.74+ · MySQL 8.0Install all of it up front — a missing dev package fails several steps later.
  • Ports 3724 · 8085 reachableAuth then world. If only the first is open, players see the realm list and then hang.

Deployment paths

All 3 shown in full

Quick-start repack

Prebuilt · fastest

Install the toolchain

Everything on this sheet assumes GCC 12+ · CMake 3.16+ · Boost 1.74+ · MySQL 8.0. Install these first — a half-configured toolchain fails three steps later with a confusing error.

bash · ubuntu 24.04
$ sudo apt update && sudo apt install -y git cmake make gcc g++ \
        libmysqlclient-dev libssl-dev libbz2-dev libreadline-dev \
        libncurses-dev libboost-all-dev mysql-server
$ cmake --version && gcc --version   # confirm before continuing

Unpack the repack

A repack carries compiled binaries and a seeded world database in one archive. Fastest route to a running realm, and the one that needs a fresh bundle every time the core moves.

bash · ubuntu 24.04
$ sha256sum -c wf-mop-5.4.8-repack.tar.zst.sha256
$ tar --zstd -xf wf-mop-5.4.8-repack.tar.zst
$ cd wf-mop && ls
# bin/  etc/  sql/  tools/

Import the seeded database

The repack's SQL bundle creates all three schemas and fills the world database in one pass. This is the step that takes the longest.

bash · mysql
$ mysql -u root -p < sql/create_databases.sql
$ mysql -u root -p world < sql/mop_world.sql
$ mysql -u root -p auth < sql/mop_auth.sql
$ mysql -u root -p characters < sql/mop_characters.sql

Extract client data

The core needs maps, vmaps, and mmaps generated from a 5.4.8 (18414) client you own. Nothing is downloaded — this reads your install and writes into the server's data directory.

bash · extraction
# run from the client root, not the server directory
$ cd /path/to/client-5.4.8
$ ~/realm/bin/mapextractor
$ ~/realm/bin/vmap4extractor && ~/realm/bin/vmap4assembler Buildings vmaps
$ ~/realm/bin/mmaps_generator --threads $(nproc)
$ mv maps vmaps mmaps dbc ~/realm/data/
Heads up: mmaps generation is the long pole here — run it with -j equal to your core count.

Point the config at your database

Two files: authserver.conf handles logins, worldserver.conf handles everything else. Copy the .dist versions before editing so you can diff against defaults later.

bash · config
$ cp etc/authserver.conf.dist etc/authserver.conf
$ cp etc/worldserver.conf.dist etc/worldserver.conf
$ $EDITOR etc/worldserver.conf   # see the key table below

Start both servers

authserver first, then worldserver. The world server holds the console — leave it in the foreground the first time so you can watch it load.

bash · launch
$ ./bin/authserver &
$ ./bin/worldserver
# "World initialized in X minutes" means you are up

Create an account and log in

Accounts live in the auth database, not in a config file. Create the first one from the worldserver console, then point the client at your host.

worldserver console
> account create admin <password>
> account set gmlevel admin 3 -1
# then, client side — edit Config.wtf
SET portal "127.0.0.1"
Max level: set MaxPlayerLevel = 90 in worldserver.conf to match this era.

Full source build

CMake · contributable

Install the toolchain

Everything on this sheet assumes GCC 12+ · CMake 3.16+ · Boost 1.74+ · MySQL 8.0. Install these first — a half-configured toolchain fails three steps later with a confusing error.

bash · ubuntu 24.04
$ sudo apt update && sudo apt install -y git cmake make gcc g++ \
        libmysqlclient-dev libssl-dev libbz2-dev libreadline-dev \
        libncurses-dev libboost-all-dev mysql-server
$ cmake --version && gcc --version   # confirm before continuing

Unpack the source bundle

The 5.4.8 tree arrives as an archive alongside its checksum. Verify before you unpack — a truncated transfer fails much later, during linking, where the cause is unrecognisable.

bash · unpack
$ sha256sum -c wf-mop-5.4.8-src.tar.zst.sha256
$ mkdir -p ~/src && tar --zstd -xf wf-mop-5.4.8-src.tar.zst -C ~/src
$ cd ~/src/core && cat BUILD_ID
# keep the BUILD_ID — the database bundle has to match it
Keep the archive. Patches ship as replacement bundles rather than as pulls, and the checksum is how you confirm which one a realm was built from.

Configure and compile

Build with tools enabled — the extractors compile from the same tree and must match your core version. Expect roughly ≈ 1 h 10 min on a modern machine.

bash · cmake
$ cmake -B ~/build -S ~/src/core \
        -DTOOLS=1 -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_INSTALL_PREFIX=$HOME/realm
$ cmake --build ~/build -j$(nproc) --target install

Create the databases

Three schemas: authentication, world content, and character state. Give the core its own MySQL user rather than reusing root.

bash · mysql
$ mysql -u root -p
> CREATE DATABASE auth DEFAULT CHARSET utf8mb4;
> CREATE DATABASE world DEFAULT CHARSET utf8mb4;
> CREATE DATABASE characters DEFAULT CHARSET utf8mb4;
> CREATE USER 'wowfiles'@'localhost' IDENTIFIED BY '<password>';
> GRANT ALL ON \`auth\`.* TO 'wowfiles'@'localhost';
> GRANT ALL ON \`world\`.* TO 'wowfiles'@'localhost';
> GRANT ALL ON \`characters\`.* TO 'wowfiles'@'localhost';
Database suite: WFDB 548. Import it into world before the first boot unless your core imports automatically.

Import and update the world database

Base import first, then every pending update in filename order. Skipping an update leaves the schema mid-migration and the core refuses to boot.

bash · sql
$ mysql -u wowfiles -p world < ~/db/wfdb-548.sql
$ for f in ~/src/core/sql/updates/world/*.sql; do \
        mysql -u wowfiles -p world < "$f"; done

Extract client data

The core needs maps, vmaps, and mmaps generated from a 5.4.8 (18414) client you own. Nothing is downloaded — this reads your install and writes into the server's data directory.

bash · extraction
# run from the client root, not the server directory
$ cd /path/to/client-5.4.8
$ ~/realm/bin/mapextractor
$ ~/realm/bin/vmap4extractor && ~/realm/bin/vmap4assembler Buildings vmaps
$ ~/realm/bin/mmaps_generator --threads $(nproc)
$ mv maps vmaps mmaps dbc ~/realm/data/
Heads up: mmaps generation is the long pole here — run it with -j equal to your core count.

Launch and watch the first boot

First boot is slow — the core caches the world database into memory. Watch for missing-data warnings; they tell you which extraction step to rerun.

bash · launch
$ ~/realm/bin/authserver &
$ ~/realm/bin/worldserver
# tail the log if you daemonize instead
$ tail -f ~/realm/logs/Server.log

Create an account and log in

Accounts live in the auth database, not in a config file. Create the first one from the worldserver console, then point the client at your host.

worldserver console
> account create admin <password>
> account set gmlevel admin 3 -1
# then, client side — edit Config.wtf
SET portal "127.0.0.1"
Max level: set MaxPlayerLevel = 90 in worldserver.conf to match this era.

Container stack

Compose · reproducible

Install Docker and Compose

The container path skips the toolchain entirely — the build happens inside the image. Best fit if you plan to run more than one realm on the same host.

bash · docker
$ curl -fsSL https://get.docker.com | sh
$ docker compose version

Unpack the stack and set your environment

One compose file brings up the database, the auth server, and the world server as separate services. Everything configurable lives in .env.

bash · compose
$ sha256sum -c wf-mop-stack.tar.zst.sha256
$ mkdir -p ~/stack && tar --zstd -xf wf-mop-stack.tar.zst -C ~/stack
$ cd ~/stack && cp .env.example .env
$ $EDITOR .env   # DB password, realm name, external IP
Volumes: the compose file keeps the databases and extracted data in named volumes, so a rebuild does not cost you the 150 GB extraction.

Bring up the database first

Start MySQL alone and let it finish initialising before the servers try to connect, otherwise the first worldserver run races the schema import.

bash · compose
$ docker compose up -d database
$ docker compose logs -f database   # wait for "ready for connections"

Extract client data into the volume

Mount your 5.4.8 (18414) client read-only and run the extractor container. This is the one step that touches files outside Docker.

bash · compose
$ docker compose run --rm \
        -v /path/to/client-5.4.8:/client:ro \
        extractor -i /client -o /data
Heads up: mmaps generation is the long pole here — run it with -j equal to your core count.

Start the servers

Both servers come up together once the data volume is populated. Compose restarts them automatically if the host reboots.

bash · compose
$ docker compose up -d authserver worldserver
$ docker compose ps
$ docker compose logs -f worldserver

Create an account and log in

Attach to the world server console inside the container to create the first account, then point your client at the host.

bash · compose
$ docker compose exec worldserver ./worldserver
> account create admin <password>
# client side — edit Config.wtf
SET portal "127.0.0.1"

Configuration keys

Edit before first launch
KeyValueWhat it does
DataDir
worldserver.conf
"./data"
Where maps, vmaps, mmaps, and DBC live after extraction.
WorldDatabaseInfo
worldserver.conf
"127.0.0.1;3306;wowfiles;<pw>;world"
Semicolon-separated. A wrong password here fails silently as a connection error.
CharacterDatabaseInfo
worldserver.conf
"127.0.0.1;3306;wowfiles;<pw>;characters"
Character state. Back this one up on a schedule.
LoginDatabaseInfo
worldserver.conf
"127.0.0.1;3306;wowfiles;<pw>;auth"
Shared with authserver.conf — both must match.
WorldServerPort
worldserver.conf
8085
Game traffic. Open this on the host firewall.
RealmID
worldserver.conf
1
Must match the id column of your realmlist row.
MaxPlayerLevel
worldserver.conf
90
Era cap for Mists of Pandaria. Setting this wrong caps characters at the wrong level.
RealmServerPort
authserver.conf
3724
Login traffic. The client connects here first.
realmlist.address
auth database
127.0.0.1
What the client is told to connect to. Use your public IP for remote players, not localhost.
realmlist.gamebuild
auth database
18414
Must match the client build (5.4.8 (18414)) exactly or logins are rejected.
client side
Config.wtf
SET portal "127.0.0.1"
Client-side file. Edit it in the client folder, not on the server.

Verify it worked

In order — each one gates the next
  • Auth server acceptsThe client reaches the realm list. If it stalls here, it is port 3724 or the gamebuild column.
  • World loads fullyThe console reports the world initialized with no missing-map warnings.
  • Character enters the worldLogin, create a character, and zone in. Falling through terrain means vmaps failed.
  • Movement is validatedRun, mount, and use a flight path. Rubber-banding points at mmaps, not at latency.

When it goes wrong

The four failures everyone hits
Client hangs after the realm listAuthServer: connection accepted, then silence
The realmlist row points somewhere the client cannot reach. Set address to your public IP, not 127.0.0.1, for anyone outside the host.
Login rejected immediatelywrong gamebuild / version mismatch
The gamebuild column must equal your client build (18414). A one-digit mismatch fails every login.
Characters fall through the worldno vmap data for map N
The vmap pass did not finish or its output never moved into data/vmaps. Rerun the extractor and assembler in order.
Core refuses to boot after a pulldatabase version mismatch
SQL updates were skipped. Apply everything in sql/updates/ in filename order — they are not idempotent out of sequence.

License terms you inherit

Copyleft obligations

This core carries copyleft terms from its lineage. Anything you distribute travels under the same license, with source.

Network clause

Serving a modified core publicly counts as distribution under the stricter terms. A private realm does not trigger it.

Access terms

Bundles are issued per operator and are not transferable. Do not rehost them or pass them on.

Client files — not licensed here

Maps, DBC, and art stay under the publisher's terms. Extract from a client you own; never redistribute them.

Keep reading