9.3 KiB
Running a 2009scape Server on Arch Linux (LAN play)
A step-by-step guide to compiling and running the game server on an Arch Linux machine, then connecting to it from another PC on your network (e.g. a gaming PC in the same house).
This targets a private/LAN setup for yourself — it deliberately skips the database
(use_auth/persist_accounts stay off), which is the simplest way to get playing. See
the notes on persistence if you want saved
accounts.
Reminder: the upstream project only supports its own live server. This guide is for running your own copy locally and is assembled from how this repo actually works — see
ARCHITECTURE.mdand the root../README.md.
0. What you'll end up with
- The game server running on your Arch machine (headless, in a terminal).
- It listens on TCP port
43594 + world_id→ 43595 with the defaultworld_id = 1. - Your gaming PC runs the 2009scape client (a separate download) pointed at the Arch machine's LAN IP.
1. Install prerequisites (Arch)
The build needs JDK 11 specifically — not a newer JDK (the project targets Java 11 and newer versions break the build). You also need git and git-lfs (the game cache is stored via Git LFS).
sudo pacman -S --needed jdk11-openjdk git git-lfs
# optional: tmux, if you want to use the run script's -x fancy session mode
sudo pacman -S --needed tmux
You do not need Maven installed — the repo ships the Maven wrapper (Server/mvnw).
If you have multiple JDKs installed, point the default at 11 for this shell:
archlinux-java status # list installed JVMs
sudo archlinux-java set java-11-openjdk
java -version # should report 11.x
Enable Git LFS once for your user:
git lfs install
2. Get the code and pull the cache
If you haven't cloned yet (upstream is on GitLab):
git clone https://gitlab.com/2009scape/2009scape.git
cd 2009scape
If you already have this repo, just make sure the LFS-backed cache is actually present
(this pulls the real binary cache files under Server/data/cache/, which are LFS pointers
until fetched):
git lfs pull
You can sanity-check the cache came down (files should be MB-sized, not tiny pointer text):
du -sh Server/data/cache
3. Configure the server for LAN play
The server config is Server/worldprops/default.conf (TOML). The defaults are already set
up for a no-database local run:
use_auth = false— any password is accepted at login.persist_accounts = false— no database required.noauth_default_admin = true— you log in as an admin (handy for testing).world_id = "1"— so the game port is 43595.enable_bots = true— the world spawns AI player bots (seeBOT_SCRIPTING.md); set tofalseif you'd rather have an empty world.
You generally do not need to change anything in the config for LAN play. The one field
people assume they must change — msip — is the management-server address (used by the
separate world-list/management backend), not the address the game client connects to. For
a single self-hosted world you can leave msip = "127.0.0.1".
Two things you may want to set:
secret_key— the client sends this on login and it must match the server's value or the connection is refused. The default is"2009scape_development". If your client uses a different key, make them match here.new_player_location/home_location— where you spawn; fine to leave default.
4. Build and run
From the repo root, the helper scripts wrap the Maven wrapper. The simplest path:
./run
./run does an incremental build and then starts the server. Other useful invocations:
./run -r # force a clean rebuild, then run (use after pulling updates)
./run -t # run the test suite only, don't start the server
./run -h # show all options
./build -qgc # clean build only (skip tests), no run
The first build takes a while (it compiles thousands of Kotlin/Java files). Grab a coffee. Subsequent runs are fast.
Under the hood this runs the fat jar with:
cd Server && java -Dnashorn.args=--no-deprecation-warning -jar builddir/server.jar
The server runs headless in your terminal. You'll see log lines ending with something like
2009Scape started in <n> milliseconds. and Starting networking.... It reads simple
commands on stdin — type stop to shut it down cleanly (or help for the list).
If you build manually with Maven instead of the scripts, run
sh mvnw cleanfirst — the clean phase installs bundled libraries (ConstLib,PrimitiveExtensions) fromServer/libs/into your local Maven repo, without which compilation fails.
Memory
The server is comfortable in default JVM memory for a small LAN world. If you enable
preload_map = true (smoother ticks) it needs ~2 GB more RAM; give the JVM more heap by
editing the java invocation in the run script, e.g. add -Xmx4g.
5. Find the server's LAN IP
On the Arch machine:
ip -4 addr show | grep inet
Note the LAN address (typically 192.168.x.y or 10.x.y.z). That's what the gaming PC
will connect to. Example used below: 192.168.1.50.
6. Open the firewall (if one is running)
Arch has no firewall enabled by default, but if you run one, allow the game port (43595 for world 1). Examples:
# firewalld
sudo firewall-cmd --add-port=43595/tcp --permanent && sudo firewall-cmd --reload
# ufw
sudo ufw allow 43595/tcp
# nftables (add to your ruleset)
# tcp dport 43595 accept
If you also enabled the browser WebSocket transport, open its port too (default
53594 + world_id = 53595).
7. Connect from the gaming PC
The client is a separate program from this server repo — download the launcher/client from the 2009scape site or use whichever client you already have. In the client's server configuration, point it at the Arch machine instead of the public server:
- Server address / IP: the Arch machine's LAN IP, e.g.
192.168.1.50 - Port:
43595(i.e.43594 + world_id) - Secret key: must match
secret_keyindefault.conf(default2009scape_development)
How you set these depends on the client build — commonly an in-launcher field, a settings
file, or a worlds/serverlist entry. Look for where the client stores the world IP/port.
Then log in with any username; with use_auth = false the password is not checked, and
with noauth_default_admin = true you'll have admin privileges (try :: commands in
chat).
8. Quick verification
- On the server machine, confirm it's listening:
ss -tlnp | grep 43595 - From the gaming PC, confirm reachability (PowerShell):
or from any Linux box:
Test-NetConnection 192.168.1.50 -Port 43595nc -vz 192.168.1.50 43595.
If the port test succeeds but login fails, the usual culprit is a secret_key mismatch
between client and server.
Optional: persistence and accounts (MySQL)
The no-database setup above forgets account-level data (credits, playtime) on restart —
but note character save data (stats, inventory) is handled separately and still saves to
Server/data/players/. If you want real authenticated accounts and persisted account
data, set in default.conf:
use_auth = true
persist_accounts = true
…and provide a MySQL/MariaDB database matching the [database] block (database_name,
_username, _password, _address, _port). On Arch:
sudo pacman -S --needed mariadb
sudo mariadb-install-db --user=mysql --basedir=/usr --datadir=/var/lib/mysql
sudo systemctl enable --now mariadb
Then create the database and import the schema shipped in the repo:
sudo mariadb -e "CREATE DATABASE global;"
sudo mariadb global < Server/db_exports/global.sql
# optional test account:
sudo mariadb global < Server/db_exports/testuser.sql
Adjust database_username/database_password in default.conf to match a MySQL user you
create. (For quick LAN use, keeping the database off is simpler.)
Docker alternative
If you'd rather not manage a local MariaDB, the repo has a Docker path (server + MySQL) —
see the Docker section of the root ../README.md. It uses
mysql.env and a config/default.conf you copy from Server/worldprops/default.conf.
Troubleshooting
| Symptom | Likely cause / fix |
|---|---|
| Build fails immediately with weird Kotlin/Java errors | Wrong JDK. Ensure java -version is 11 (sudo archlinux-java set java-11-openjdk). |
Build fails about missing ConstLib/primextends |
You built without a clean. Run ./build -qgc (or sh mvnw clean in Server/). |
| Cache errors / tiny cache files | LFS not pulled. Run git lfs install then git lfs pull. |
Port 43595 is already in use |
Another server instance is running, or change world_id. |
| Client can't reach the server | Firewall on the Arch box, wrong LAN IP, or client pointed at the wrong port. Verify with ss/nc (step 8). |
| Connects but login refused | secret_key mismatch between client and default.conf. |
| World feels crowded with bots | Set enable_bots = false (and/or max_adv_bots = 0) in default.conf. |