If you’ve been living under a rock, Palworld is the newest game to take the internet by storm. It’s been coined:

Pokémon, with guns

It’s a crafting survival game where you, and friends, can build up a base and collect “Pals” together. The “and friends” is why we’re here today. One can run a server when they are actively playing, but what if you want an always on server, that your friends can hop on, even when your gaming machine is powered off?

Introducing the concept of a “dedicated server”. An instance of the game world that is always on, and not tied to when a player is actively playing. Dedicated servers make a lot of sense on locally running hardware, that has a hardwired internet connection, and is always on. Hence this makes one’s home lab an ideal place to run a dedicated server.

As a software engineer, I often use containerization to deploy new software, which is why we’ll walk through how to use Docker, and Docker Compose to run your very own Palworld dedicated server.

Prerequisite Steps

  1. You have Docker installed
  2. You know how to set up port forwarding on your router

Run Option 1: Docker Compose Service

This is my preferred method of running Docker containers, as it allows me to keep track of all the details in a single docker-compose.yaml file, and not have to remember, or write down various $ docker run commands. Here is a minified docker-compose.yaml:

version: "3.7"

services:
  palworld:
    image: thijsvanloef/palworld-server-docker
    container_name: palworld
    ports:
      - 8211:8211/udp
      - 27015:27015/udp
    environment:
      - PUID=99
      - PGID=100
      - PLAYERS=32
      - MULTITHREADING=TRUE
      - COMMUNITY=true  # Disable this if you do not want your server to show up in the community servers tab, USE WITH SERVER_PASSWORD!
      # Enable the environment variables below if you have COMMUNITY=true
      - SERVER_PASSWORD="I love Greg Hilston"
      - SERVER_NAME="GregHilston.com Example"
      - ADMIN_PASSWORD="supersecretpassword"
    volumes:
        - /home/ghilston/config/palworld:/palworld/
    restart: unless-stopped

Be sure to modify the volumes, and environment entries to match what you desire.

You’ll notice that we’re leveraging thijsvanloef/palworld-server-docker After having dug around through a few Palworld server docker images, his seemed to be the best at the time.

Then all you have to run is $ docker compose up -d and your container will start.

Run Option 2: Docker Run Command

I do not personally run straight $ docker run commands, but here is an equivalent to the docker compose approach above. Recall, you’ll have to modify some of the environment and volume data.

docker run -d \
  --name palworld \
  -p 8211:8211/udp \
  -p 27015:27015/udp \
  -e PUID=99 \
  -e PGID=100 \
  -e PLAYERS=32 \
  -e MULTITHREADING=TRUE \
  -e COMMUNITY=true \
  -e SERVER_PASSWORD="I love Greg Hilston" \
  -e SERVER_NAME="GregHilston.com Example" \
  -e ADMIN_PASSWORD="supersecretpassword" \
  -v /home/ghilston/config/palworld:/palworld/ \
  --restart unless-stopped \
  thijsvanloef/palworld-server-docker

Port Forward

Log in to your router as an admin and ensure that ports 8211 and 27015 both map to the IP address of your home server, with those same ports, for UDP.

Modifying Game Server Settings

Shell exec into your container, when its running: $ docker exec -it palworld /bin/bash

and modify the file: /palworld/Pal/Saved/Config/LinuxServer/PalWorldSettings.ini. This file is empty by default. Follow the discussion and steps highlighted here on how to get this empty file to be filled with content.

Documentation on the values can be found here

Admin Commands

Are documented here

How To Connect To Your Server

  1. launch the game
  2. select Join Multiplayer Game
  3. at the bottom there’s a little gray text box where you can type in an IP and port. Type in the [IP address of your machine]:8211. For yourself, locally, you should be able to use a local IP of your server. While your friends will need to use your public IP address. You can find this out any number of ways, the fastest way is to leverage a site like whatismyip.com.

Performance Tweak

My friend Zach, learned of a tweak one can make to their configuration file to reduce lag and rubber banding. He said you can add the following to your palworld/Pal/Saved/Config/LinuxServer/Engine.ini:

; Online Subsystem Utils Configuration
; Adjusting tick rates for LAN and Internet servers to enhance the frequency of game state updates,
; leading to smoother gameplay and less desynchronization between server and clients.
[/script/onlinesubsystemutils.ipnetdriver]
LanServerMaxTickRate=120  ; Sets maximum ticks per second for LAN servers, higher rates result in smoother gameplay.
NetServerMaxTickRate=120  ; Sets maximum ticks per second for Internet servers, similarly ensuring smoother online gameplay.

; Player Configuration
; These settings are crucial for optimizing the network bandwidth allocation per player,
; allowing for more data to be sent and received without bottlenecking.
[/script/engine.player]
ConfiguredInternetSpeed=104857600  ; Sets the assumed player internet speed in bytes per second. High value reduces chances of bandwidth throttling.
ConfiguredLanSpeed=104857600       ; Sets the LAN speed, ensuring LAN players can utilize maximum network capacity.

; Socket Subsystem Epic Configuration
; Tailoring the max client rate for both local and internet clients, this optimizes data transfer rates,
; ensuring that the server can handle high volumes of data without causing lag.
[/script/socketsubsystemepic.epicnetdriver]
MaxClientRate=104857600          ; Maximum data transfer rate per client for all connections, set to a high value to prevent data capping.
MaxInternetClientRate=104857600  ; Specifically targets internet clients, allowing for high-volume data transfer without restrictions.

; Engine Configuration
; These settings manage how the game's frame rate is handled, which can impact how smoothly the game runs.
; Smoother frame rates can lead to a better synchronization between client and server.
[/script/engine.engine]
bSmoothFrameRate=true    ; Enables the game engine to smooth out frame rate fluctuations for a more consistent visual experience.
bUseFixedFrameRate=false ; Disables the use of a fixed frame rate, allowing the game to dynamically adjust frame rate for optimal performance.
SmoothedFrameRateRange=(LowerBound=(Type=Inclusive,Value=30.000000),UpperBound=(Type=Exclusive,Value=120.000000)) ; Sets a target frame rate range for smoothing.
MinDesiredFrameRate=60.000000 ; Specifies a minimum acceptable frame rate, ensuring the game runs smoothly at least at this frame rate.
FixedFrameRate=120.000000     ; (Not active due to bUseFixedFrameRate set to false) Placeholder for a fixed frame rate if needed.
NetClientTicksPerSecond=120   ; Increases the update frequency for clients, enhancing responsiveness and reducing lag.

Thanks Zach!