# Linux dedicated-server setup

Linux package **0.5.0-linux.1** contains the 0.5.0 map server, indexer, Java telemetry agent and a Python installer. Windows downloads remain 0.5.0. Linux x86-64 is supported by this package; ARM is not included. Python 3.8+ is required only for setup. The web interface is embedded: Node, Go and Python packages are not needed on the target server.

This is the first Linux package. Automated tests cover setup, real Linux binaries and JVM telemetry fixtures; a live Linux Project Zomboid multiplayer session and Helmforge deployment still need validation. It does not include a Linux terrain renderer wizard or a container image.

## Install

Run as the **same non-root account that runs Project Zomboid**, with read access to the game installation. Do not use sudo for the installer. The game must have its executable `start-server.sh` and `jre64/bin/java`. Use installation paths without spaces or shell punctuation.

Download the archive and its checksum from the download website (the source repository is private), then:

```sh
sha256sum -c PZLiveMap-0.5.0-linux.1-linux-amd64.tar.gz.sha256
tar -xzf PZLiveMap-0.5.0-linux.1-linux-amd64.tar.gz
cd PZLiveMap-0.5.0-linux.1-linux-amd64
python3 install.py --game /home/steam/pzserver --install-dir /home/steam/pzlivemap \
  --origin https://map.example.com --name 'My Zomboid Server'
```

Replace the example paths and URL. Omit `--origin` for localhost testing. The installer prompts for administrator and team passwords, checks the installed game APIs, creates protected configuration and accounts, and indexes shops and loot. Administrator login is `admin`. Existing destination directories are refused, preventing accidental overwrites. Failed setup removes only its newly created destination. No game files, profiles or saves are edited and no services are restarted.

Start the map with `/home/steam/pzlivemap/start-map.sh`. It listens on `127.0.0.1:3000` by default. In a container or for LAN access, supply `--listen 0.0.0.0:3000` and the correct `--origin` during installation; restrict access at your firewall/proxy as appropriate. Ingest stays on loopback.

On the next normal game stop/start, change the game startup command to:

```sh
/home/steam/pzlivemap/start-game.sh -servername servertest
```

Keep your actual existing game arguments, including `-servername`, `-cachedir` and `-nosteam` where applicable. The wrapper runs the original launcher and adds the Java agent through `JAVA_TOOL_OPTIONS`. Use this wrapper exactly once; remove any older manual LiveMap `-javaagent` argument first. It preserves existing Java options. Steam updates do not replace the wrapper. Recheck compatibility after game updates:

```sh
/home/steam/pzserver/jre64/bin/java -cp /home/steam/pzlivemap/tools/pzlivemap-agent.jar \
  pzlivemap.agent.Check /home/steam/pzserver
```

If migrating an old Lua integration, remove only `PZLiveMap` from the selected profile's `Mods=` list while the game is stopped; preserve other mods. Players need no LiveMap installation.

## Terrain

Game assets and rendered terrain are not distributed. Export a `Map.pzmap` with the Windows portable renderer using the same game assets as the dedicated server. Copy the package to Linux, stop the map process (the game may continue running), then run from the extracted Linux package:

```sh
python3 import-map.py --install-dir /home/steam/pzlivemap \
  --game /home/steam/pzserver --profile /home/steam/Zomboid/Server/servertest.ini \
  --bundle /home/steam/Map.pzmap
```

The importer checks the map fingerprint, tile paths, counts and calibration before activating staged terrain. It backs up configuration and preserves previous terrain for rollback; allow room for both copies plus 5 GiB headroom. Restart the map after import. The importer expects the JSON-format `config/config.yaml` written by this installer; if you convert that file to YAML, use manual migration instead.

For manual migration, copy an already activated tile directory from an existing Windows installation, copy its entire `map` configuration section into the Linux config, and change `tiles` to the Linux directory. Preserve all other Linux configuration values. Blank terrain before import does not indicate telemetry failure.

## Run automatically with systemd

As the game account, after installation:

```sh
mkdir -p ~/.config/systemd/user
cp /home/steam/pzlivemap/pzlivemap.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now pzlivemap.service
journalctl --user -u pzlivemap.service -f
```

For startup without logging in, a host administrator can enable lingering with `sudo loginctl enable-linger steam` (replace `steam` with your account). This service starts only the map, not the game. Containers without a user systemd session should use their supervisor to run `start-map.sh`.

## Cloudflare, panels and separate hosts

Use your own Cloudflare tunnel: route `map.example.com` to `http://127.0.0.1:3000` when the connector runs on the same host. This installer does not install or authorize Cloudflare. Use an HTTPS origin and secure cookies for the public site. Your reverse proxy must support WebSockets. Subpaths such as `/pzmap` are not supported; use a dedicated hostname.

For a panel, use persistent storage for the whole installation and configure the game to use `start-game.sh`. This requires the game and map processes to share the snapshot directory under the same account (or deliberately configured permissions). If separate containers are used, mount the agent and snapshot paths at the same absolute paths. Helmforge-specific templates are not included or tested.

For a map website on a different host, the snapshot requires a separate secure transport; the installer does not set this up. Installing the map alongside the Linux game server is the supported setup path for this package.

## Updates, troubleshooting and removal

Stop the map before replacing its binaries. If updating the agent, also stop the game normally. Back up the LiveMap directory, extract the new archive separately, run its agent compatibility check, and replace only `pzlivemap`, `pzindexer` and `tools/pzlivemap-agent.jar`. Preserve `config`, `data`, and launcher scripts. Start the game with the wrapper and restart the map. This installer is for fresh setup, not in-place upgrades.

For “Live player count unavailable”, check game logs for `PZLiveMap`, confirm `data/live/state.json` updates about once per second, and confirm the game is actually started through the wrapper. A snapshot older than 15 seconds becomes unavailable. Check writable permissions and Java compatibility before re-rendering terrain. Map logs are on stdout or in the systemd journal.

To remove integration, stop the game normally and restore its original startup command. Disable the map service with `systemctl --user disable --now pzlivemap.service`, remove the copied unit, and run `systemctl --user daemon-reload`. Keep your data backup before deleting the installation directory. No Steam game files require restoration.

## Building from source

With Node, Go (version specified in go.mod), Python 3 and JDK 17+ installed, run `bash scripts/build-linux.sh`. This builds the embedded frontend, agent, Linux binaries, archive and SHA-256 sidecar. Only the listed public payload files are packaged; game files, saves and credentials are excluded.
