How to Create a Tibia (OTServ) Server on Linux with TFS

Practical guide to running an OTServ based on The Forgotten Server (TFS) on Ubuntu Linux: dependencies, compilation, MySQL, login, and firewall.

Running your own Tibia server (OTServ) is a project that mixes C++ compilation, MySQL database configuration, Lua scripting, and Linux network management. This guide focuses on getting a server based on The Forgotten Server (TFS) 1.5 running from scratch on an Ubuntu 24.04 LTS VPS, from cloning the repository to the client connecting.

The persona for this tutorial is the new OTServ owner with basic familiarity with the Linux command line who wants a functional test server before customizing maps, sprites, and scripts. The path is: install dependencies, compile TFS, configure MySQL, adjust config.lua, and open the ports on the firewall. On reasonable hardware, the whole procedure takes between 30 and 45 minutes.

We won’t cover map customization (RME), Lua script creation, or shared login server setup for an OT-list — those are topics for dedicated tutorials. The focus here is the minimum viable path to having a server that accepts real connections.

Prerequisites

Prerequisites

Ubuntu 24.04 LTS (or Debian 12) with sudo access, at least 2 GB of RAM, 10 GB of free disk space, and a stable public IP. SSH working, UFW firewall available, and TCP ports 7171/7172 unblockable at the provider.

System Ubuntu 24.04 LTS
Minimum RAM 2 GB
TCP Ports 7171 + 7172
Target client Tibia 8.60

Confirm you are logged in as a user with sudo and refresh the package index before starting:

sudo apt update && sudo apt upgrade -y

Installing compilation dependencies

TFS 1.5 is written in C++17 and uses Boost, LuaJIT (or Lua 5.4), the MySQL client library, PugiXML, and CryptoPP. You need all of them, plus the GCC toolchain and CMake to generate the build files.

01

Install the compilation toolchain and development libraries:

sudo apt install -y build-essential cmake git
sudo apt install -y libluajit-5.1-dev libmariadb-dev libboost-system-dev \
  libboost-iostreams-dev libboost-filesystem-dev libboost-date-time-dev \
  libpugixml-dev libcrypto++-dev libfmt-dev

build-essential brings GCC, G++, and make. The libboost-*-dev packages are the specific Boost modules TFS actually uses — installing libboost-all-dev works but pulls in ~300 MB of unnecessary code.

02

Create a dedicated user to run the server (good isolation practice):

sudo adduser --disabled-password --gecos "" otserv
sudo usermod -aG sudo otserv

The --disabled-password flag blocks password login — you access it via sudo -iu otserv from your main user.

Cloning and compiling TFS

With dependencies installed, download the source code and build the binary.

03

Switch to the otserv user and clone the official repository:

sudo -iu otserv
cd ~
git clone --depth 1 https://github.com/otland/forgottenserver.git tfs
cd tfs

The --depth 1 flag downloads only the latest commit (instead of the entire history, which is hundreds of MB). If you need to contribute back to the project, do a full clone later.

04

Generate the project with CMake and compile using all available cores:

mkdir build && cd build
cmake ..
make -j$(nproc)

nproc returns the number of CPU threads — on a VPS with 4 vCPUs, this parallelizes the build into 4 jobs. Compilation takes between 3 and 10 minutes depending on the hardware. When it finishes, the tfs binary appears in ~/tfs/build/.

Out-of-memory error during compilation

On VPS instances with less than 2 GB of RAM, make -j$(nproc) can run out of memory while compiling heavy files. If you see internal compiler error: Killed (program cc1plus), retry with make -j1 (serial compilation, slower but stable).

MySQL database configuration

TFS persists accounts, characters, houses, guilds, and items in a relational database. MariaDB is the default implementation on Ubuntu.

05

Exit the otserv user (back to your sudo shell) and install the MySQL server:

exit
sudo apt install -y mariadb-server
sudo mysql_secure_installation

mysql_secure_installation is an interactive wizard: set a strong root password, remove anonymous users, block remote root login, and remove the test database. Accept everything with Y.

06

Create the database and the OTServ user:

sudo mariadb

Inside the MySQL prompt:

CREATE DATABASE forgottenserver CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'otserv'@'localhost' IDENTIFIED BY 'CHANGE_THIS_PASSWORD';
GRANT ALL PRIVILEGES ON forgottenserver.* TO 'otserv'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Replace CHANGE_THIS_PASSWORD with a strong password (at least 16 random characters — use openssl rand -base64 24 to generate one).

07

Import the initial TFS schema:

sudo -iu otserv
cd ~/tfs
mariadb -u otserv -p forgottenserver < schema.sql

The schema.sql file is at the root of the cloned repository and creates all the necessary tables (accounts, players, houses, guilds, etc).

Server configuration

With the database ready, adjust config.lua to point at the correct credentials and define world parameters.

08

Copy the configuration template:

cd ~/tfs
cp config.lua.dist config.lua
nano config.lua

Adjust these essential fields:

ip = "0.0.0.0"
mysqlHost = "127.0.0.1"
mysqlUser = "otserv"
mysqlPass = "CHANGE_THIS_PASSWORD"
mysqlDatabase = "forgottenserver"
mysqlPort = 3306
loginProtocolPort = 7171
gameProtocolPort = 7172
statusProtocolPort = 7171
serverName = "My OTServ"
worldType = "pvp"

ip = "0.0.0.0" makes TFS listen on all interfaces — required to accept external connections. If you prefer to restrict to a specific interface, use the VPS public IP.

Plain-text password

config.lua stores the MySQL password in plain text. Make sure the file permissions are restricted: chmod 600 config.lua. Never commit that file to a public repository (add it to .gitignore).

Firewall release and first start

TFS uses two TCP ports: 7171 for login (authentication and character selection) and 7172 for the game (movement, chat, real-time combat).

09

Switch back to your sudo user and open the ports in UFW:

exit
sudo ufw allow 7171/tcp
sudo ufw allow 7172/tcp
sudo ufw reload
sudo ufw status

If UFW is inactive (Status: inactive), enable it with sudo ufw enable — but first confirm that port 22 (SSH) is open, otherwise you’ll lock yourself out.

10

Start the server to validate it:

sudo -iu otserv
cd ~/tfs/build
./tfs

If everything went well, you’ll see something like:

The Forgotten Server - Version 1.5
>> Loading config
>> Establishing database connection... MySQL 10.11.x
>> Running database manager
>> Loading vocations
>> Loading items
>> Loading script systems
>> Loading monsters
>> Loading map
>> Loaded map
>> Loaded all modules, server starting up...
>> A server has been started on 0.0.0.0:7171.

Verification

On another machine (or your own desktop), open a terminal and test connectivity:

telnet YOUR_VPS_IP 7171

If you see Connected to ... and the terminal hangs waiting for input, the port is open and TFS is listening. Press Ctrl+] and type quit to exit.

For a real test with a Tibia 8.60 client, adjust the Tibia.dat/Tibia.spr files in the client folder to point at your IP instead of the official login.tibia.com — tools like OTClient let you do this via init.lua.

Troubleshooting

MySQL connection failed

If TFS prints MySQL connection failure!, check three things:

  1. The service is running: sudo systemctl status mariadb
  2. Credentials match: try manual login with mariadb -u otserv -p forgottenserver
  3. mysqlHost in config.lua is 127.0.0.1, not localhost (on some setups the Unix socket fails but TCP works)

Port already in use

The bind: Address already in use error on port 7171 means another process is using it. Identify it with:

sudo ss -tulpn | grep 7171

If it’s an old TFS instance, kill it with pkill tfs and try again.

Client connects but doesn’t pass login

The client connects on 7171 (login) but fails to move to 7172 (game). It’s almost always the firewall blocking 7172 while 7171 is open — re-run sudo ufw status and open the missing port. If the server is behind NAT (uncommon on a VPS), forward both ports.

Next steps

  • Configure TFS to run as a systemd service instead of a manual process — makes automatic restart easier on crashes
  • Edit Lua scripts in data/scripts/ to customize quests, NPCs, and events
  • Use RME (Remere’s Map Editor) on Windows to edit data/world/forgottenserver.otbm
  • Set up automated daily database backups with mysqldump in cron
  • If you’re putting this in production for real players, a Hostini VPS already comes with fixed IPv4, DDoS protection, and NVMe storage — eliminating the three most common network issues in home hosting.

Frequently asked questions

Which TFS version should I use for a new OTServ?

The 1.5 branch of The Forgotten Server (master branch on GitHub) is the most widely used today on customized servers and runs on 8.60 clients with adjustments. If you need an older client (7.4, 7.72), look for specific forks like TFS 0.x or OTX — they have different compilation requirements.

How much RAM does a small OTServ consume?

A TFS 1.5 server with up to 100 online players stabilizes between 400 MB and 1 GB of RAM, depending on the map and the number of active Lua scripts. MySQL adds another 200-400 MB. To start with headroom, 2 GB of RAM is sufficient.

Can I run OTServ directly as root?

Technically yes, but it's bad practice. Create a dedicated user (e.g. otserv) and run the binary as them. If an exploit on the server is leveraged, the attacker stays restricted to that user's scope instead of compromising the entire system.

Why doesn't my Tibia client connect even with the server running?

The three most common causes are: firewall blocking 7171/7172 (check with sudo ufw status), wrong server IP in config.lua (the ip field), or the login server crashed silently (check the tfs log). Test the port from outside with telnet IP 7171 before touching the client.

How do I back up the OTServ database?

Use mysqldump to export the schema and the data: mysqldump -u otserv -p forgottenserver > backup.sql. Schedule that command in cron daily and send the backup to another disk or external storage. Restore with mysql -u otserv -p forgottenserver < backup.sql.

Do I need a dedicated IP for OTServ?

Yes, or at least a stable address. The Tibia client connects directly to the IP listed in config.lua and the login server — a residential dynamic IP changes and drops your players. A VPS solves this with a fixed IPv4.

Topics:
Next steps VPS, dedicated or managed panel for FiveM, SAMP, MTA, Tibia and more.Host your game server with Hostini →
Was this tutorial helpful?
Chat on WhatsApp