Build the MMORPG server locally, prove that OTClient can reach it, and only then open the required game connection to remote players.
The Forgotten Server is a free and open-source MMORPG server emulator written in C++. This installation-first guide explains the documented Ubuntu and Arch Linux compilation paths, how to distinguish a successful build from a working game server, and what must be verified before internet exposure. After local operation is confirmed, we show how to connect the validated TCP listener to a public Localtonet endpoint without inbound router port forwarding, firewall changes, a public IP address, or VPN setup. Where the available project documentation does not establish a command, port, credential, or runtime default, we identify the gap rather than inventing a value.
๐ What's in this guide
Understand the complete self-hosting workflow
The Forgotten Server, commonly abbreviated as TFS, is an MMORPG server emulator written in C++ and derived from the OpenTibia Server project. Its repository contains the C++ source tree, CMake build definitions, game data, a distributed configuration template, a database schema, and related project files. Players connect with OTClient, but a successful source compilation alone does not create a complete playable deployment.
It helps to divide the work into separate layers. First, obtain a known version of the source. Second, install a supported compiler toolchain and the required development libraries. Third, generate build files and compile the executable. Fourth, prepare the runtime configuration, database, game data, and client compatibility needed by the selected TFS version. Fifth, start the server and verify it from the host or local network. Only after those stages work should a remote-access tunnel be introduced.
Keeping these layers separate makes failures much easier to diagnose. A compiler error belongs to the build layer. A database authentication or schema error belongs to the runtime layer. A connection refused message usually points to the listener, address, port, or process state. A remote-only failure may involve the Localtonet client, the tunnel lifecycle, the selected local target, or the public endpoint entered in OTClient.
Localtonet forwards traffic to an existing service. It does not compile TFS, create its database, select an OTClient protocol version, or cause a failed server process to begin listening. Complete a local client test before adding the tunnel.
Prerequisites and evidence-backed limitations
The general TFS compilation documentation identifies Git, CMake, a compiler, and several libraries as build requirements. GCC or Clang is recommended. The documented library set includes Boost, GMP, Lua, a MySQL C connector, PugiXML, and fmt. Distribution-specific instructions install packages that satisfy the applicable toolchain and library requirements.
For Ubuntu, the current documented procedure requires Ubuntu 24.04 or later because of package requirements. For Arch Linux, the documented procedure uses the current package repositories through pacman. The project also documents compilation paths for other operating systems, including Windows and macOS, but those commands are outside this guide because the supplied evidence only establishes complete command sequences for Ubuntu and Arch.
| Requirement | Why it is needed | What this guide can verify |
|---|---|---|
| Supported build environment | Provides the compiler, build tools, headers, and libraries | Ubuntu 24.04 or later and Arch Linux have documented package commands |
| Git | Downloads the source repository | The official compilation paths use Git clone commands |
| CMake and compiler | Generate native build files and compile TFS | Both documented Linux paths install and use CMake and a compiler toolchain |
| Runtime configuration | Defines the server's operational settings | The repository includes config.lua.dist, but the supplied evidence does not establish the complete production configuration procedure |
| Database preparation | Supports persistent server data | The repository includes schema.sql and uses a MySQL client dependency, but database provisioning commands and credentials are not established here |
| Compatible OTClient | Connects a player to the server | The project states that OTClient can connect, but the supplied evidence does not define a universal OTClient setup or endpoint |
| Localtonet client | Establishes an outbound connection to our relay | Install it on the server host or another device that can reach the confirmed TFS listener |
You also need ordinary administrative access to install operating-system packages and enough storage and memory for the selected source, compiler workload, database, map, and game data. The evidence supplied for this guide does not publish minimum CPU, memory, or disk requirements, so we do not assign unsupported hardware figures. Resource needs can vary substantially with the selected data pack, map, scripts, player count, compiler settings, and database workload.
Database passwords, administrator accounts, player credentials, Localtonet device tokens, and private endpoints must remain secret. Use unique credentials and grant only the access each component requires. A Localtonet device token identifies the client device and must never be guessed, published, or committed to the TFS repository.
Choose the TFS version before compiling
Version selection affects far more than the build. It can affect game protocol compatibility, OTClient behavior, database expectations, configuration options, scripts, maps, and data packs. The TFS repository README offers two broad starting paths: compile the source or download a packaged release. The release identified as TFS 1.6 is described by the project as a stable protocol 13.10 release.
Cloning the repository without checking out a tag obtains the repository's current default branch. That is not the same commitment as selecting the TFS 1.6 release. If your objective is reproducibility, record the exact release, tag, or commit used for the build. Keep the associated configuration, schema, data, and OTClient selection aligned with that version instead of mixing files from unrelated branches or releases.
This guide presents the documented source compilation commands exactly as supplied for Ubuntu and Arch. Those clone commands target the repository rather than pinning TFS 1.6. If you require 1.6 specifically, select that release deliberately before treating the resulting build as a 1.6 deployment. Do not infer the version merely from a successful compilation.
Compile The Forgotten Server on Ubuntu
The documented Ubuntu process requires Ubuntu 24.04 or later. Run these commands from an account that can use sudo. Package installation may prompt for confirmation or report that some packages are already installed.
Install the documented build packages
Install Git, CMake, the standard build toolchain, Lua and LuaJIT development files, MySQL client development files, Boost components, PugiXML, Crypto++, and fmt with the official Ubuntu package command.
Clone the source recursively
Download the TFS repository and its required submodules using the documented recursive clone command.
Generate the build files
Enter the repository, create a dedicated build directory, enter it, and point CMake at the parent source directory.
Compile the project
Run make from the generated build directory. Treat a nonzero exit or compiler error as a failed build and resolve it before attempting runtime configuration.
1. Install the required software
sudo apt install git cmake build-essential libluajit-5.1-dev libmysqlclient-dev libboost-system-dev libboost-iostreams-dev libpugixml-dev libcrypto++-dev libfmt-dev libboost-locale-dev libboost-json-dev liblua5.3-dev
This is the package list established by the current Ubuntu compilation documentation. If the package manager reports that a package cannot be found, first confirm that the host is actually running Ubuntu 24.04 or later and that its configured package repositories are appropriate for that installation. Replacing package names with guesses from an older Ubuntu release can produce mismatched headers or a partially satisfied build.
2. Download the source
git clone --recursive https://github.com/otland/forgottenserver.git
The --recursive option initializes included submodules while cloning. Let the command complete before entering the repository. If an interrupted download leaves an uncertain working tree, verify the checkout and submodules rather than assuming the source is complete.
3. Generate the build files
cd forgottenserver
mkdir build && cd build
cmake ..
CMake examines the project and available dependencies, then generates build files in the separate build directory. Read the final CMake output carefully. A created directory is not proof that configuration succeeded. Missing headers, libraries, compiler support, or CMake checks must be resolved before compilation.
4. Build TFS
make
A clean return from make indicates that the compilation stage completed. Warnings should still be reviewed, especially if they point to local modifications or unsupported compiler behavior. The supplied Ubuntu instructions do not provide a complete runtime launch sequence, service unit, database provisioning flow, or production directory layout, so compilation is the end of what can be reproduced exactly from this evidence.
Do not create a public tunnel immediately after make. First prepare the configuration and database appropriate to the exact source version, start the executable successfully, identify the real listening address and port, and connect with a compatible OTClient over the local network.
Compile The Forgotten Server on Arch Linux
The Arch procedure uses pacman to update the system and install the required build packages. Its documented sequence differs slightly from the Ubuntu path: it generates files with cmake . -B build and invokes the build using make -C build.
Update Arch and install the required packages
Synchronize and update the system, then install the base development group, Git, CMake, LuaJIT, Boost, the MariaDB client library, PugiXML, Crypto++, and fmt.
Download the source repository
Use the clone command published in the Arch compilation instructions.
Generate files in the build directory
Enter the repository and tell CMake to use the repository as its source while writing generated build files into build.
Compile and locate the executable
Build from the generated directory. The Arch documentation states that the resulting executable is located at ./build/tfs.
1. Install the required software
sudo pacman -Syu
sudo pacman -S base-devel git cmake luajit boost boost-libs libmariadbclient pugixml crypto++ fmt
Finish the system update before compiling. If package installation fails, resolve repository, mirror, signing, or package-manager issues at the operating-system layer. Removing a documented dependency simply to make the package command shorter can move the failure to CMake or the compiler.
2. Download the source
git clone https://github.com/otland/forgottenserver.git
This is the clone command shown in the Arch instructions. The broader TFS compilation wiki uses a recursive clone, while the Arch page displays the command above. That documentation difference should not be silently rewritten. If CMake later reports missing source associated with a submodule, compare the checkout against the requirements of the exact tag or commit selected.
3. Generate the build files
cd forgottenserver
cmake . -B build
This keeps generated output under build while using the current repository directory as the source. CMake must complete successfully before the next step.
4. Compile the executable
make -C build
The documented output location is:
./build/tfs
The presence of that file confirms that an executable was produced. It does not confirm that runtime dependencies, database access, game data, client protocol compatibility, or network listeners are ready.
Configure and start TFS without inventing defaults
This is the point where many short tutorials become unsafe: they copy a port, database account, configuration filename, or launch command from an unrelated TFS version. The supplied project evidence establishes that the repository contains config.lua.dist, schema.sql, game data, and a compiled executable. It does not establish a complete version-specific runtime procedure, default credentials, a universal game port, or a supported service-manager definition.
Consequently, the correct approach is to derive runtime values from the exact release or commit you built. Review that version's distributed configuration template and schema before changing anything. Do not combine the configuration template from one release with an executable from another unless the project explicitly documents that combination.
Configuration checklist
Before starting the process, account for each of the following items:
- The exact TFS release, tag, or commit represented by the executable.
- The runtime configuration expected by that version.
- The database engine and schema expected by the selected source.
- A dedicated database account with only the permissions TFS requires.
- The game data, map, scripts, and other runtime files expected by the build.
- The listener address and every port explicitly configured for client operation.
- An OTClient build compatible with the selected game protocol.
- Administrative account handling and recovery procedures.
- A backup plan for the database, configuration, and customized game data.
The supplied project evidence does not document the endpoint address, port, or transport setting to use for every installation. Read the configuration belonging to your selected TFS version and verify the live listener after startup. Do not paste a familiar game-server port from an unrelated tutorial into Localtonet.
Start TFS from the working directory and with the runtime files required by the chosen version. Because an exact launch command and working-directory contract are not established in the supplied evidence, this guide does not fabricate one. The Arch documentation proves that the executable is built at ./build/tfs, but an executable path alone does not prove which invocation, current directory, arguments, or service wrapper is required for correct runtime operation.
On the first successful startup, inspect the server output for configuration parsing, data loading, database connectivity, schema compatibility, map loading, and network-listener messages. A process that exits after a fatal database or map error is not a running server. A process that remains visible but never opens the required listener is also not ready for OTClient or Localtonet.
Secure the runtime before exposure
Use dedicated credentials rather than reusing an administrative database login. Restrict database access to the hosts that need it. Keep configuration files containing secrets out of public repositories. Review accounts and permissions before inviting players. Remove test credentials, rotate anything that may have been shared, and back up the database before upgrades or schema changes.
Run the game server with the least operating-system privilege practical for its documented requirements. Remote access should be limited to the game listener that players need. A database service, management panel, shell service, debugger, or development endpoint should not be included merely because it runs on the same machine.
Verify the server locally before opening remote access
Local verification should answer three independent questions: is the TFS process healthy, is it listening where expected, and can the intended OTClient complete a connection? Passing only one of these checks is not enough.
Confirm a clean server startup
Review the TFS output and resolve fatal configuration, database, schema, map, script, or data-loading errors. The process must remain running.
Identify the actual listener
Read the selected version's configuration and inspect the running host to confirm the address, port, and transport actually opened by TFS. Record observed values instead of relying on memory.
Test from the server host
Where the chosen OTClient and server configuration support a host-local test, connect to the configured local endpoint and confirm that the server handles the session.
Test from another LAN device
Connect with the compatible OTClient using the server's reachable LAN address and confirmed port. This detects loopback-only bindings and host firewall restrictions before a tunnel is added.
Exercise a real client session
Verify the applicable login and game flow, then watch the TFS output for disconnects or protocol errors. A basic socket opening is weaker evidence than a functioning client session.
If the process works from the host but not another LAN machine, investigate the server's bind address, host firewall, local routing, and the address entered in OTClient. Localtonet removes the need for inbound router port forwarding, but it does not override an operating-system rule that prevents the Localtonet client device from reaching the local target.
Client compatibility deserves special attention. The TFS 1.6 release is identified as protocol 13.10, but that does not prove that every OTClient build supports it or that every data pack uses identical behavior. Match the client to the selected server version and validate the combination locally.
| Observed result | Likely problem area | Next check |
|---|---|---|
| TFS exits during startup | Runtime configuration, database, schema, map, scripts, or data | Read the first fatal error and correct that dependency before networking work |
| Process runs but no listener appears | Listener configuration or incomplete startup | Compare runtime output with the exact version's configuration |
| Host-local connection works but LAN fails | Bind address, host firewall, or LAN route | Confirm that the service is not restricted to loopback |
| OTClient reaches the endpoint but cannot proceed | Protocol, client version, credentials, or game configuration | Match OTClient to the selected TFS release and inspect server logs |
| LAN works but public access fails | Localtonet client, tunnel state, target, or public endpoint | Confirm the device is connected, the tunnel is started, and the target matches the validated listener |
Connect remote OTClient players with Localtonet
Once OTClient works against the confirmed local or LAN endpoint, Localtonet can publish that listener without inbound router port forwarding, firewall changes, VPN setup, or a public IP address. Our client application establishes an outbound connection from the device to a Localtonet relay server. A running TCP tunnel then provides a public host and port that forwards traffic to the selected local IP address and port.
Use a TCP tunnel only after you have verified that the required TFS client endpoint is actually TCP. The topic strongly suggests a persistent game-client connection, but the exact TFS endpoint and all ports required by a particular deployment must come from that deployment's configuration and live listeners. If the client workflow requires more than one independently reachable TCP listener, each required listener must be evaluated and exposed appropriately rather than assuming one tunnel covers every port.
Install and run the Localtonet client
Run our client on the TFS host or on another device that can reach the verified TFS listener. The client device needs outbound connectivity to establish its relay connection.
Authenticate or select the client device
Use the device-specific authentication token associated with the client that will carry the tunnel. Keep the token private and do not place it in documentation, screenshots, scripts, or public repositories.
Select an available relay server
Choose from the server or region values currently available in the Localtonet dashboard. Availability can vary, so this guide does not hardcode a server code or region.
Create a TCP tunnel to the verified target
Set the local target to the IP address and TCP port proven during local testing. If Localtonet runs on the same machine as TFS, use the address through which the service is genuinely reachable from that client process. If it runs on another LAN device, use the TFS host's reachable LAN address.
Start the tunnel
Creating a tunnel does not make it run. Start it with the Start button and confirm that the selected Localtonet device remains connected.
Use the assigned public host and port
Configure the compatible remote OTClient with the public host and port assigned to the running tunnel, wherever that client build allows the server endpoint to be entered. Stop or delete the tunnel when public access is no longer required.
The assigned public endpoint is not the same as the local TFS address. The local target belongs in the tunnel configuration, while remote players use the public Localtonet host and port. Keep both values in your operational notes so they are not accidentally swapped.
Expose only the listener required by players. Keep the database, shell access, development tools, and administrative interfaces private unless each has a separate, justified, and access-controlled workflow. Review TFS account security, scripts, data packs, and server updates before inviting untrusted users.
A Localtonet tunnel is available only while the selected client device is connected and the tunnel is running. The TFS process must also remain healthy and reachable from that device. If the host sleeps, the server exits, the local address changes, or the Localtonet client disconnects, remote sessions cannot continue through that tunnel.
Test from outside the host network
Perform the final test from a genuinely external network rather than reconnecting through the same LAN and assuming the public route was used. Enter the exact assigned public host and port in the compatible OTClient. At the same time, watch the TFS runtime output and the Localtonet tunnel state. This separates three useful outcomes:
- No connection reaches TFS, which points toward the public endpoint, stopped tunnel, disconnected device, or incorrect local target.
- A connection reaches TFS but is rejected, which points toward client protocol, credentials, server configuration, or application behavior.
- A complete session works, which confirms the build, runtime, local listener, tunnel target, and remote client path together.
Operate the server and tunnel responsibly
Treat the server as a maintained service rather than a one-time compilation experiment. Record the source version, compiler environment, package set, configuration revision, schema state, OTClient version, local listener, and public endpoint. This makes future rebuilds and incident diagnosis substantially more reliable.
Back up the database and customized data before upgrades. Test upgrades away from the live environment where possible. Source changes can affect schemas, configuration keys, scripts, maps, or client compatibility even when compilation still succeeds. Never assume that replacing only the executable is a complete upgrade procedure.
For planned downtime, stop accepting new sessions, shut down TFS according to the behavior documented by the selected version, and then stop the Localtonet tunnel. When restoring service, start and verify the database and TFS first, confirm the local listener, ensure the Localtonet client is connected, and then start the tunnel. This order prevents a publicly reachable endpoint from pointing at an unverified or half-started service.
Localtonet also supports platform-wide Token and Tunnel webhooks for Connected and Disconnected state changes in a selected Token Group. These webhooks report connectivity state for a token or tunnel. They are not TFS gameplay events, account events, or proof that a player completed login. If you use them operationally, treat them as connectivity signals and continue monitoring the game server separately.
A tunnel configuration may exist without being started. A started tunnel may have a connected Localtonet client while TFS is stopped. TFS may be listening while OTClient is incompatible. Operational checks should verify every layer rather than reducing health to one status indicator.
Troubleshoot compilation, startup, and remote connections
CMake cannot find a required library
Return to the package command for your actual distribution and verify that it completed successfully. Confirm the operating-system version, particularly the Ubuntu 24.04 minimum. Do not mix Ubuntu and Arch package names. Clear evidence of a missing dependency should be solved at the package or CMake layer, not by editing network settings.
The compiler stops with an error
Focus on the first meaningful compiler error rather than the final summary line. Confirm that the source checkout is complete, the selected branch or tag is intentional, and the generated build files correspond to that checkout. Local source modifications can also introduce failures. If a crash occurs after a successful build, the general TFS compilation guidance suggests compiling debug binaries so symbols are retained, but the supplied evidence does not give a verified debug-build command, so one is not invented here.
The executable exists but exits immediately
Compilation has succeeded, but runtime initialization has not. Read the process output for the first fatal error. Typical categories to investigate are configuration parsing, database connectivity, schema compatibility, map loading, game data, scripts, file permissions, and working-directory assumptions. The exact correction depends on the selected TFS version and error message.
OTClient cannot connect on the same LAN
Confirm that TFS is still running and that the live listener matches the address and port entered in OTClient. Check whether the service is bound only to loopback. Verify that the host firewall allows the LAN connection and that the client can route to the server address. Finally, validate OTClient compatibility with the selected TFS protocol.
The LAN connection works but Localtonet does not
Confirm that the Localtonet client is running on the selected device and shows as connected. Check that the tunnel is explicitly started, because creation alone does not start it. Compare the tunnel's local IP and port with the exact endpoint that succeeded during LAN testing. If the Localtonet client is on another device, make sure that device can reach the TFS host directly.
The public endpoint opens, but login or gameplay fails
If TFS records the incoming connection, the tunnel has already carried traffic to the local process. Investigate protocol compatibility, client configuration, credentials, database state, scripts, and any endpoint information returned by the game workflow. Some applications advertise addresses or use multiple connections after an initial exchange. The supplied evidence does not define TFS's complete connection topology, so inspect the behavior and version-specific configuration rather than assuming one public endpoint is sufficient.
The tunnel worked and then stopped
Verify all lifecycle dependencies: the TFS process, its local listener, the Localtonet client, the selected device connection, and the tunnel's running state. Also check whether the host slept, restarted, changed its LAN address, or lost outbound connectivity. Restart components in dependency order and retest locally before blaming the public endpoint.
Frequently asked questions
What is The Forgotten Server?
The Forgotten Server is a free and open-source MMORPG server emulator written in C++. It is a fork of the OpenTibia Server project, and players can connect to it using a compatible OTClient.
Can I install TFS without compiling it?
The project README lists downloadable releases as an alternative to compiling. Check the selected release for its actual package contents, operating-system compatibility, configuration requirements, and startup instructions. Do not assume that a downloaded package includes a configured database or ready-to-use game environment.
Which Ubuntu version should I use to compile TFS?
The current documented Ubuntu compilation procedure requires Ubuntu 24.04 or later because of package requirements. Package names and availability should not be assumed to match older Ubuntu releases.
Does a successful build mean the game server is ready?
No. It means the compiler produced the program. A usable deployment still needs version-compatible runtime files, configuration, database preparation, game data, a successful startup, an active listener, and a compatible OTClient test.
What port does The Forgotten Server use?
This guide does not assign a universal port because the supplied project evidence does not establish one for every version and deployment. Read the configuration for the exact TFS version you built, start the server, and confirm the live listener on the host. Use that verified port for local testing and the Localtonet target.
Why use a Localtonet TCP tunnel for TFS?
After you confirm that the required TFS game endpoint uses TCP, our TCP tunnel can publish that local listener through a public host and port. The Localtonet client creates an outbound relay connection, so inbound router port forwarding, firewall changes, a public IP address, and VPN setup are not required for the tunnel workflow.
Does creating a Localtonet tunnel start it automatically?
No. Tunnel creation and tunnel operation are separate lifecycle states. After creating the TCP tunnel, start it with the Start button. It remains available only while the selected client device is connected and the tunnel is running.
Should Localtonet run on the same machine as TFS?
It can run on the TFS host or on another device that can reach the server's verified local IP address and port. Running it elsewhere requires reliable LAN connectivity from that device to TFS. In either case, target the endpoint you have already tested from the Localtonet client device.
Does Localtonet configure TFS, OTClient, or the database?
No. Localtonet provides connectivity to an existing local service. TFS compilation, database provisioning, schema management, game configuration, account administration, data packs, and OTClient compatibility remain part of the TFS deployment.
Can I expose the database through the same game tunnel?
A TCP tunnel forwards to one configured local target. More importantly, the game database should not be exposed merely because remote players need the game listener. Keep database access private and limited to authorized systems unless you have a separate, carefully secured administrative requirement.
Connect your verified TFS listener with Localtonet
Compile and configure The Forgotten Server, prove the selected OTClient works locally, and identify the real TCP listener. Then use Localtonet to create and start a tunnel to that exact target and give remote players the assigned public host and port.
Get Started Free โ