Roll your server

...with Blackjack and hookers!

Hosting your own Quake World server is not mandatory, but since not many of existing welcome hackers, I wrote down some notes for anyone who wishes to have their own. There are two mainstream server setups:

The mvdsv is dominant game engine choice for Quake World server. It has whole ecosystem built around it and it's extremely lightweight. The KTX is mod which gives you basic quality of life features like map voting, custom HUDs and so on. This is kinda standard even though alternatives exist.

FTEQW is its own beast. This all-in-one package has more visual features and its inner workings differ which leaves room for hacking.



0. Prerequisites

Both options require you to have VPS (obviously) with GNU\Linux installed. I would personally recommend either Debian or Rocky linux, latter of which will be this tutorial aimed at.

I would also highly recommend running your server containerised. It's quite possible that you would want to run more configs and/or servers on your VPS and managing them outside of Docker can be messy. In order to install Docker properly, follow your distro official documentation. For Rocky linux it would be this doc.

Last thing, you will need official content files (.pak files) with game textures, models and so on. Luckily, the game costs less than cup of coffee, so this should not be a real problem.



1.a mvdsv + KTX setup

On your VPS in non-root users home, create directory qwhvh and inside it create these subdirs:

mkdir qwhvh qwhvh/id1 qwhvh/ktx qwhvh/demos qwhvh/logs && cd qwhvh

Copy your PAK0.pak and PAK1.pak files from Quake game files inside the id1/ dir. Easiest way to do it (if you don't have SFTP already established) is to temporarily upload them on the web and curl them directly to the directory.

When done, create main config files for the server.

touch ktx/server.cfg docker-compose.yml Dockerfile
Bellow, I will paste working configs for these three files.

Dockerfile:

FROM debian:bookworm-slim AS build RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential cmake git ca-certificates libcurl4-openssl-dev && \ rm -rf /var/lib/apt/lists/* WORKDIR /src RUN git clone --depth 1 https://github.com/QW-Group/mvdsv.git && \ # download the mvdsv source code (the engine) cd mvdsv && \ # land binary spot is mvdsv/build/mvdsv cmake -B build -DCMAKE_BUILD_TYPE=Release . && \ # cmake: build in Release mode and compile it. cmake --build build -j$(nproc) RUN git clone --depth 1 https://github.com/QW-Group/ktx.git && \ # Download the KTX source code (the gameplay mod) cd ktx && \ # land final bonary in /ktx cmake -B build -DCMAKE_BUILD_TYPE=Release -DBOT_SUPPORT=ON . && \ # cmake: add -DBOT_SUPPORT=ON so bots are compiled in cmake --build build -j$(nproc) FROM debian:bookworm-slim RUN apt-get update && apt-get install -y --no-install-recommends \ # install only the runtime libraries the server needs libcurl4 ca-certificates && \ # which are libcurl4 for networking ca-certificates for HTTPS rm -rf /var/lib/apt/lists/* && \ useradd -m -u 1000 qw # create an unprivileged user "qw" to ride the container WORKDIR /qw # COPY --from=build /src/mvdsv/build/mvdsv ./mvdsv ## COPY --from=build /src/ktx/build/qwprogs.so ./ktx/qwprogs.so ### prepare server directories COPY --from=build /src/ktx/resources/example-configs/ktx/bots ./ktx/bots ## RUN mkdir -p id1 qw ktx demos logs && chown -R qw:qw /qw # USER qw EXPOSE 27500/udp 28000/tcp # cocument which ports the container uses: 27500/udp (the game) and 28000/tcp (QuakeTV) ENTRYPOINT [ # the command that runs when the container starts "./mvdsv", # launch mvdsv binary and add flags: "-port", "27500", # listen on UDP port 27500 "-game", "ktx", \ # load the KTX mod "+set", "sv_progtype", "1", # tell mvdsv the mod is a native .so library "+set", "sv_progsname", "qwprogs", \ # the mod file is named qwprogs(.so) "+maxclients", "12", "+maxspectators", "6", \ # engine hard cap of 12 total slots; This is set BEFORE exec so the engine allocates slots before the config runs "+exec", "server.cfg"] # up to 6 of those are spectators; specs always takes seats of players

docker-compose.yml:

services: qwhvh: build: . container_name: qwhvh restart: unless-stopped mem_limit: 1g # hard cap the container to use at most 1 GB RAM mem_reservation: 256m # soft target to keep it around 256 MB dns: # pin explicit DNS servers for the container (more in pt 3. Known issues) - 1.1.1.1 - 8.8.8.8 ports: - "27500:27500/udp" # Quake World (mandatory) 27500 is standard but you may choose your own - "28000:28000/tcp" # QuakeTV (optional) volumes: - ./id1:/qw/id1:ro,Z - ./ktx:/qw/ktx:Z - ./demos:/qw/demos:Z - ./logs:/qw/logs:Z

server.cfg: (note, change placeholder values)

hostname "yourserver.example" // the server's display name, shown in the clients' server browser sv_admininfo "your-email" // admin contact info serverinfo welcome "hello world" // this will be printed on master server NOT to players sv_speedcheck 0 // speed-hack detection sv_minping 0 // don't punish low/odd pings sv_kicktop 0 // kdetect specific packet-abuse exploit sv_unfake 0 // detects "fakeshaft"/aim-deception packet tricks sv_cheats 0 // engine built-in console cheats off (no god/noclip/give) allow_download 1 // master download switch allow_download_skins 1 // allow downloading custom skins, allow_download_models 1 // models, allow_download_sounds 1 // sounds, allow_download_maps 1 // maps, allow_download_demos 1 // and recordings // KTX set k_allow_fbskins 1 // allow fullbright skins set k_allow_hud 1 // allow custom HUDs set k_allow_fakeshaft 1 // allow fakeshaft (essential) set k_allow_hideplayers 1 // allow client-side hiding of players set k_allow_pext 1 // allow protocol extensions set k_allow_scripts 1 // allow client scripting // bots (frogbots) set k_fb_skill 7 // bot skill 0-20; 7 is default set k_fb_chat 0 // set to 0 otherwise it clutters the chat set k_defmode ffa // FFA is standard for HvH set k_free_mode 5 // who can call free modes (5 = all) set k_allowed_free_modes 255 // which modes are allowed (255 = all, incl. FFA) set k_motd1 "welcome to yourserver" // line1 set k_motd2 "hack vs hack" // line2 set k_motd3 "happy gibbing" // line3 set k_motd_time 5 // all 3 lines stay shown for 5 seconds set k_maxclients 6 // optional? the Dockerfile and docker-compose seems overide this set k_maxspectators 6 // same as above sv_forcespec_onfull 1 // when players full, extra joins become spectators - rcon_password "CHANGE-ME" // your password for managing server from the client sv_crypt_rcon 1 // encrypt rcon traffic so the password isn't sent in the clear sv_phs 1 // potentially-hearable-set sound optimization setmaster master.quakeservers.net:27000 // master server set to quakeservers, but you may add more floodprotmsg "Easy easy now" // message shown to players who trigger flood protection floodprot 4 4 10 // max 4 messages per 4 seconds, then mute for 10 seconds map dm3 // starting map

To configure the game modes, we need to build the container first. From inside the qwhvh directory run:

docker compose build --no-cache

Now we may modify the game mode configs as the KTX generated the files needed. These can be found in ktx/configs/usermodes/. Check out example game mode configs in the KTX project repository.

Let's start the server.

docker compose up -d

Then open the game ports on firewall.

sudo firewall-cmd --permanent --add-port=27500/udp --reload

And open the ports in VPS application firewall settings in your account dashboard as well.

That's it. Happy hacking!



1.b FTEQW setup

WIP



2. Registering master server

This is optional but useful if you want your server to be found in game client server list. Config files considered single master server, the quakeservers.net, but you may register to any other master server, or to multiple at same the time. Just don't forget to declare your master server(s) in config files.

To register your server on quakeservers.net, simply follow this link and fill up their forms.



3. Customizing the server

Most common way to customize your server in competetive hack vs hack is adding custom maps and textures. To add custom map, simply curl the .bsp file you want from the quakeworld.nu map index directly to the qwhvh/id1/maps/.

To add custom textures (e.g. your server logo) to the game, use the qPAK tool. There is this nice Quake Wiki guide on how to use it.



4. Known issues

Sometimes the server shows offline status, but is actually running. Logs show Setting nomaster mode and SV_BroadcastUpdateServerList: No master servers configured, repeated on every restart. The container simply lost DNS resolution and can't turn master server FLDN into an IP, and keeps falling back to "nomaster". This occur when no explicit DNS servers are marked down in docker-compose.yml or if something on the host disrupts Dockers networking (firewall reload or cronjob).

To fix this, simply re-build the container.