-
Notifications
You must be signed in to change notification settings - Fork 0
Manual Linux Installation
This guide provides a comprehensive, step-by-step manual installation procedure for Project Zomboid Optimiser (PZO) on Linux distributions (Ubuntu, Debian, Arch, Fedora, openSUSE, Gentoo), Steam Deck (SteamOS), Flatpak Steam, and Headless Linux Dedicated Servers / Containers.
If you prefer not to run the automated shell script (pzo_optimizer.sh), or are configuring a headless environment or custom directory layout, follow the manual steps below.
Before starting, acquire the PZO release files from the PZO Releases page:
-
Client Engine:
PZOptimEngine.jar(or downloadPZO_Optimizer_macOS_Linux.zipwhich contains all client binaries). -
Native Linux Acceleration Companion:
libpzo_native64.so(AVX2 SIMD math, high-precision timer governor, and native thread scheduler). -
Dedicated Server Engine (Servers only):
PZOServerEngine.jar. - Steam Workshop Mod (Optional, Recommended): Subscribe to Project Zomboid Optimiser on Steam Workshop to enable the in-game F10 Control Center, F9 HUD, and main menu status telemetry.
The game root folder is the directory containing ProjectZomboid64.json and projectzomboid.jar. Depending on your environment, locate your path:
| Platform / Setup | Typical Path |
|---|---|
| Standard Steam (Native Linux) | ~/.local/share/Steam/steamapps/common/ProjectZomboid/ |
| Alternative Steam Path |
~/.steam/steam/steamapps/common/ProjectZomboid/ or ~/.steam/root/steamapps/common/ProjectZomboid/
|
| Flatpak Steam | ~/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/common/ProjectZomboid/ |
| Steam Deck (Internal SSD) | /home/deck/.local/share/Steam/steamapps/common/ProjectZomboid/ |
| Steam Deck (MicroSD Card) | /run/media/mmcblk0p1/steamapps/common/ProjectZomboid/ |
| Custom Steam Library Drive | /<mount-point>/steamapps/common/ProjectZomboid/ |
| Dedicated Server (Standard / Docker) |
/opt/pzserver/, /home/steam/pzserver/, or /home/container/ (Pterodactyl) |
Note
On certain Linux depots and game versions, game files may reside inside a nested projectzomboid subfolder (e.g. ProjectZomboid/projectzomboid/). The target directory is whichever folder directly contains ProjectZomboid64.json.
Assign your game directory to a variable for ease of use in terminal commands:
# Example for standard Steam:
export PZ_DIR="$HOME/.local/share/Steam/steamapps/common/ProjectZomboid"
# Example for Flatpak Steam:
# export PZ_DIR="$HOME/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/common/ProjectZomboid"
# Example for Steam Deck:
# export PZ_DIR="/home/deck/.local/share/Steam/steamapps/common/ProjectZomboid"Always backup ProjectZomboid64.json before making modifications:
cd "$PZ_DIR"
cp ProjectZomboid64.json ProjectZomboid64.json.bak-
Copy
PZOptimEngine.jarinto your game root directory:cp /path/to/PZOptimEngine.jar "$PZ_DIR/" -
Copy
libpzo_native64.sointo the game directory as well as the native library search paths:cp /path/to/libpzo_native64.so "$PZ_DIR/" mkdir -p "$PZ_DIR/linux64" "$PZ_DIR/natives" cp /path/to/libpzo_native64.so "$PZ_DIR/linux64/" cp /path/to/libpzo_native64.so "$PZ_DIR/natives/"
Open ProjectZomboid64.json in your favorite text editor (e.g., nano, vim, kate, gedit, or VS Code):
nano "$PZ_DIR/ProjectZomboid64.json"Make the following adjustments:
You can configure the client entrypoint in one of two ways:
-
Option A (Recommended - JavaAgent): Keep
"mainClass": "zombie/gameStates/MainScreenState"and add"-javaagent:PZOptimEngine.jar"to"vmArgs". -
Option B (Direct Main Entrypoint): Set
"mainClass": "com/pzoptimizer/PZOEntrypoint".
Ensure "PZOptimEngine.jar" and "." are in the "classpath" array:
"classpath": [
"PZOptimEngine.jar",
".",
"java/.",
"java/projectzomboid.jar"
]In the "vmArgs" array:
- Ensure
-Djava.library.pathpoints to Linux library directories (do not let it point towin64/):"-Djava.library.path=linux64/:natives/:." - Add the native C++ acceleration agent:
"-agentlib:pzo_native64" - If using the JavaAgent approach, add:
"-javaagent:PZOptimEngine.jar"
Match -Xmx to your system memory capacity:
| Total System RAM | Recommended -Xmx
|
Recommended -Xms
|
|---|---|---|
| 8 GB RAM (or Steam Deck) | -Xmx6144m |
-Xms2048m |
| 16 GB RAM | -Xmx8192m |
-Xms4096m |
| 32 GB+ RAM | -Xmx12288m |
-Xms4096m |
Warning
Do not assign 100% of your system RAM to -Xmx. Project Zomboid uses off-heap direct native memory for OpenGL textures, persistent VBOs, FMOD audio buffers, and Netty networking. Leaving 2–4 GB for the OS and off-heap allocations prevents out-of-memory kernel kills.
{
"mainClass": "zombie/gameStates/MainScreenState",
"classpath": [
"PZOptimEngine.jar",
".",
"java/.",
"java/projectzomboid.jar"
],
"vmArgs": [
"-javaagent:PZOptimEngine.jar",
"-agentlib:pzo_native64",
"-Djava.library.path=linux64/:natives/:.",
"-Xmx8192m",
"-Xms4096m",
"-XX:+UseG1GC",
"-XX:+PerfDisableSharedMem",
"-XX:InitiatingHeapOccupancyPercent=45",
"-XX:G1ReservePercent=15",
"-XX:+AlwaysPreTouch",
"-XX:+UnlockExperimentalVMOptions",
"-XX:+UseSuperWord",
"-XX:MaxInlineLevel=15",
"-XX:InlineSmallCode=2500",
"-XX:+UseNUMA",
"--enable-native-access=ALL-UNNAMED",
"--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED",
"-Djava.awt.headless=true",
"-Dzomboid.steam=1"
]
}PZO's in-game UI and main menu indicator check ~/Zomboid/Lua/pzo_status.json to verify engine activation and pass configuration parameters to Lua scripts.
Run the following command to generate this file:
mkdir -p "$HOME/Zomboid/Lua"
cat << 'EOF' > "$HOME/Zomboid/Lua/pzo_status.json"
{"optimized":true,"ram_gb":8,"g1gc":true,"pretouch":true,"version":"0.9.9.5"}
EOF(Adjust "ram_gb": 8 to match the integer GB you allocated in -Xmx).
By default, Steam on Linux runs the Native Linux version of Project Zomboid. However, if you explicitly forced Proton under Game Properties > Compatibility > Force the use of a specific Steam Play compatibility tool, note the following differences:
Follow the standard Linux steps in Part 1. Your paths are:
- Game Root:
/home/deck/.local/share/Steam/steamapps/common/ProjectZomboid/ - User Data:
/home/deck/Zomboid/Lua/pzo_status.json - Native Library:
libpzo_native64.so
When running via Proton, the game runs the Windows executable inside a wine prefix:
- Copy
PZOptimEngine.jarandpzo_native64.dll(not.so) into your game directory. - In
ProjectZomboid64.json, ensure-Djava.library.path=win64/:natives/:.is retained. - The Zomboid user profile lives inside the Proton prefix. Also copy
pzo_status.jsoninto the prefix:export PROTON_PZ="$HOME/.local/share/Steam/steamapps/compatdata/108600/pfx/drive_c/users/steamuser/Zomboid/Lua" mkdir -p "$PROTON_PZ" cp "$HOME/Zomboid/Lua/pzo_status.json" "$PROTON_PZ/pzo_status.json"
When setting up a dedicated server on Ubuntu Server, Debian, Arch Linux, Pterodactyl, or Docker:
Copy PZOServerEngine.jar into your dedicated server directory (the folder containing ProjectZomboid64.json or projectzomboid.jar):
cp /path/to/PZOServerEngine.jar /opt/pzserver/[!CRITICAL] DO NOT modify
"mainClass"on Linux Dedicated Servers! Keep"mainClass": "zombie/network/GameServer". The Linux server binary (ProjectZomboid64/pzexe) specifically checks ifmainClassis"zombie/network/GameServer". If changed, the launcher misidentifies the process as a desktop client and triggers a failingSteamAPI_Init()call, aborting the server immediately. Always load PZO via"-javaagent:PZOServerEngine.jar"in"vmArgs".
{
"mainClass": "zombie/network/GameServer",
"classpath": [
"java/.",
"java/projectzomboid.jar"
],
"vmArgs": [
"-javaagent:PZOServerEngine.jar",
"-Djava.awt.headless=true",
"-Xmx8192m",
"-Xms4096m",
"-Dzomboid.server=1",
"-Dzomboid.steam=1",
"-Dzomboid.znetlog=1",
"-Djava.library.path=linux64/:natives/:.",
"-Djava.security.egd=file:/dev/urandom",
"-XX:+UseZGC",
"-XX:-OmitStackTraceInFastThrow",
"-XX:+UseCompactObjectHeaders",
"-XX:+UseStringDeduplication",
"-XX:+PerfDisableSharedMem",
"-XX:+DisableExplicitGC",
"-XX:+ExitOnOutOfMemoryError"
]
}Headless servers need proper Steamworks SDK library linking:
- Ensure
steam_appid.txtexists in the server directory with content108600:echo "108600" > steam_appid.txt
- Symlink
steamclient.soto the 64-bit Steam SDK path (if not already present):mkdir -p "$HOME/.steam/sdk64" cp -f linux64/steamclient.so "$HOME/.steam/sdk64/steamclient.so" 2>/dev/null || true
Ensure that the files you copied are owned by your standard user (not root) and have appropriate read/execute permissions:
# For standard desktop user:
chmod 644 "$PZ_DIR/PZOptimEngine.jar"
chmod 755 "$PZ_DIR/libpzo_native64.so" "$PZ_DIR/linux64/libpzo_native64.so" 2>/dev/null || true
chmod 644 "$PZ_DIR/ProjectZomboid64.json"
chmod -R 755 "$HOME/Zomboid/Lua"
# If commands were inadvertently executed with sudo:
sudo chown -R "$USER:$USER" "$PZ_DIR" "$HOME/Zomboid"Launch Project Zomboid via Steam (or start your server daemon). Verify the engine using the following checks:
- Check the top-right corner of the Project Zomboid main menu.
- Hovering over the gear icon should display:
"PZO Engine Active".
- Load any single-player or multiplayer game.
- Press F10 to open the Control Center.
- Tab 7 ([+] JVM Engine) should display live hardware gauges, real-time GC pause latency, and multi-core thread status.
Check your log output:
- Client log:
~/Zomboid/console.txt - Engine log:
~/Zomboid/Lua/pzo_engine.log - Server telemetry:
~/Zomboid/Lua/pzo_server_telemetry.json
Look for the initialization banner:
[PZO Agent] Build 42 JVM Instrumentation Agent Active
[PZO Agent] Bytecode Transformer registered successfully
[PZONative] Loaded libpzo_native64.so
[PZO] Project Zomboid Optimiser Initialized
-
Cause: On a dedicated server,
"mainClass"was changed away from"zombie/network/GameServer". -
Fix: Restore
"mainClass": "zombie/network/GameServer"and loadPZOServerEngine.jarusing"-javaagent:PZOServerEngine.jar"in"vmArgs".
-
Cause:
-Xmxwas set higher than physical free RAM or system swap. -
Fix: Lower
-XmxinProjectZomboid64.json(e.g. from-Xmx16384mto-Xmx8192mor-Xmx6144m).
-
Cause: The native library was not placed in a directory listed in
-Djava.library.path. -
Fix: Ensure
libpzo_native64.sois copied to$PZ_DIR/linux64/libpzo_native64.soand$PZ_DIR/libpzo_native64.so, and verify that-Djava.library.path=linux64/:natives/:.is included in"vmArgs".
- PZO fully coexists with ZombieBuddy on Linux.
- In
ProjectZomboid64.json, you can safely keep both:"-agentlib:zbNative", "-agentlib:pzo_native64", "-javaagent:PZOptimEngine.jar"
To completely revert to stock vanilla settings:
- Restore your original JSON configuration:
cp -f "$PZ_DIR/ProjectZomboid64.json.bak" "$PZ_DIR/ProjectZomboid64.json"
- Delete the PZO binaries:
rm -f "$PZ_DIR/PZOptimEngine.jar" "$PZ_DIR/PZOServerEngine.jar" rm -f "$PZ_DIR/libpzo_native64.so" "$PZ_DIR/linux64/libpzo_native64.so" "$PZ_DIR/natives/libpzo_native64.so" rm -f "$HOME/Zomboid/Lua"/pzo_* "$HOME/Zomboid"/pzo_*
- Alternatively, in Steam, right-click Project Zomboid > Properties > Installed Files > Verify integrity of game files.